Facebook
From Little Marten, 3 Years ago, written in Plain Text.
This paste is a reply to Untitled from Edgy Motmot - view diff
Embed
Download Paste or View Raw
Hits: 131
  1. `include "defines.vh"
  2. module decode_unit #(
  3.                 parameter  INSTR_WIDTH  = 16,   // instructions are 16 bits in width
  4.                 parameter  R_ADDR_WIDTH = 5
  5.  
  6.         )(
  7.                 input  wire  [INSTR_WIDTH-1:0]   instruction,
  8.                 output reg   [`OPCODE_COUNT-1:0] opcode_type,
  9.                 output wire  [`GROUP_COUNT-1:0]  opcode_group,
  10.                 output reg   [R_ADDR_WIDTH-1:0]  opcode_rd,
  11.                 output reg   [R_ADDR_WIDTH-1:0]  opcode_rr,
  12.                 output reg               [11:0]  opcode_imd,
  13.                 output reg                [2:0]  opcode_bit
  14.         );
  15.  
  16. /*Fiindca register file-ul procesorului nostru (ATtiny20)
  17. are doar 16 registre, putem ignora bitii Rr si Rd de pe pozitiile 9 si 8
  18. (Atmel garanteaza ca, din motive de compatibilitate, vor fi mereu setati
  19. pe 1, sau, echivalent, vor fi folosite numai registrele R16 ? R31).
  20. Deci opcode = 000111rdxxxxxxxx devifne 00011111xxxxxxxx. (Btw, that's ADD)
  21. */
  22.  
  23.         always @* begin
  24.                   casez (instruction)
  25.                         16'b0000_11??_????_????: begin
  26.                                 opcode_type = `TYPE_ADD;
  27.                                 opcode_rd   = instruction[8:4];
  28.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  29.                         end
  30.                         16'b0001_11??_????_????: begin
  31.                                 opcode_type = `TYPE_ADC;
  32.                                 opcode_rd   = instruction[8:4];
  33.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  34.                         end
  35.                         16'b0010_00??_????_????: begin
  36.                                 opcode_type = `TYPE_AND;
  37.                                 opcode_rd   = instruction[8:4];
  38.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  39.                         end
  40.                                 16'b0010_01??_????_????: begin
  41.                                 opcode_type = `TYPE_EOR;
  42.                                 opcode_rd   = instruction[8:4];
  43.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  44.                         end
  45.                         /* TODO 5: LD_Y */
  46.                         16'b1000_000?_????_1000: begin
  47.                                 opcode_type = `TYPE_LD_Y;
  48.                                 opcode_rd   = instruction[8:4];
  49.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  50.                                 opcode_imd  = 12'bx;
  51.                         end
  52.                         /* TODO 3: LDI */
  53.                         16'b1110_????_????_????: begin
  54.                                 opcode_type = `TYPE_LDI;
  55.                                 opcode_rd   = {1'b1, instruction[7:4]};
  56.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  57.                                 opcode_imd  = {4'b0, instruction[11:8], instruction[3:0]};
  58.                         end
  59.                         /* TODO 6,7: instructions */
  60.                         16'b1010_0???_????_????: begin
  61.                                 opcode_type = `TYPE_LDS;
  62.                                 opcode_rd   = {1'b1, instruction[7:4]};
  63.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  64.                                 opcode_imd  = {~instruction[8], instruction[8], instruction[10:9], instruction[3:0]};
  65.                         end
  66.                         16'b0010_11??_????_????: begin
  67.                                 opcode_type = `TYPE_MOV;
  68.                                 opcode_rd   = instruction[8:4];
  69.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  70.                                 opcode_imd  = 12'bx;
  71.                         end
  72.                         16'b1001_010?_????_0001: begin
  73.                                 opcode_type = `TYPE_NEG;
  74.                                 opcode_rd   = instruction[8:4];
  75.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  76.                         end
  77.                         16'b0000_0000_0000_0000: begin
  78.                                 opcode_type = `TYPE_NOP;
  79.                                 opcode_rd   = {R_ADDR_WIDTH{1'bx}};
  80.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  81.                         end
  82.                         16'b0010_10??_????_????: begin
  83.                                 opcode_type = `TYPE_OR;
  84.                                 opcode_rd   = instruction[8:4];
  85.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  86.                         end
  87.                         16'b0001_10??_????_????: begin
  88.                                 opcode_type = `TYPE_SUB;
  89.                                 opcode_rd   = instruction[8:4];
  90.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  91.                         end
  92.                         /*TODO 4: STS */
  93.                         16'b1010_1???_????_????: begin
  94.                                 opcode_type = `TYPE_STS;
  95.                                 opcode_rd   = {R_ADDR_WIDTH{1'bx}};
  96.                                 opcode_rr   = {1'b1, instruction[7:4]};
  97.                                 opcode_imd  = {~instruction[8], instruction[8], instruction[10:9], instruction[3:0]};
  98.                         end
  99.                                 /* TODO : De codificat instructiunile din laborator. */
  100.  
  101.                                 default: begin
  102.                                         opcode_type = `TYPE_UNKNOWN;
  103.                                         opcode_rd   = {R_ADDR_WIDTH{1'bx}};
  104.                                         opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  105.                                 end
  106.                 /*TODO : completati cu opcodes ale voastre.
  107.                   Where can I find such opcodes? Make them up or read the lab and see
  108.                   they're at http://www.atmel.com/images/Atmel-0856-AVR-Instruction-Set-Manual.pdf  */
  109.                   /* Cand gasiti o instructiune de UAL, setati opcode_type la valoarea corecta */
  110.                   /*  instruction seamana cu un ADD? -> opcode_type = `TYPE_ADD; */
  111.                   endcase
  112.         end
  113.  
  114.         assign opcode_group[`GROUP_ALU_ONE_OP] =
  115.                 (opcode_type == `TYPE_NEG);
  116.         assign opcode_group[`GROUP_ALU_TWO_OP] =
  117.                 (opcode_type == `TYPE_ADD) ||
  118.                 (opcode_type == `TYPE_ADC) ||
  119.                 (opcode_type == `TYPE_SUB) ||
  120.                 (opcode_type == `TYPE_AND) ||
  121.                 (opcode_type == `TYPE_EOR) ||
  122.                 (opcode_type == `TYPE_OR);
  123.         assign opcode_group[`GROUP_ALU] =
  124.                 opcode_group[`GROUP_ALU_ONE_OP] ||
  125.                 opcode_group[`GROUP_ALU_TWO_OP];
  126.  
  127.         assign opcode_group[`GROUP_LOAD_DIRECT] =
  128.                 (opcode_type == `TYPE_LDS);
  129.         assign opcode_group[`GROUP_LOAD_INDIRECT] =
  130.                 (opcode_type == `TYPE_LD_Y);
  131.  
  132.         assign opcode_group[`GROUP_STORE_DIRECT] =
  133.                 (opcode_type == `TYPE_STS);
  134.         assign opcode_group[`GROUP_STORE_INDIRECT] =
  135.                 0;
  136.  
  137.         assign opcode_group[`GROUP_REGISTER] =
  138.                 /* TODO 3: LDI */
  139.                 (opcode_type == `TYPE_LDI) ||
  140.                 (opcode_type == `TYPE_MOV);
  141.  
  142.         assign opcode_group[`GROUP_LOAD] =
  143.                 opcode_group[`GROUP_LOAD_DIRECT] ||
  144.                 opcode_group[`GROUP_LOAD_INDIRECT];
  145.         assign opcode_group[`GROUP_STORE] =
  146.                 opcode_group[`GROUP_STORE_DIRECT] ||
  147.                 opcode_group[`GROUP_STORE_INDIRECT];
  148.         assign opcode_group[`GROUP_MEMORY] =
  149.                 (opcode_group[`GROUP_LOAD] ||
  150.                  opcode_group[`GROUP_STORE]);
  151. endmodule
  152.