Facebook
From Mature Dormouse, 3 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 83
  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:
  47.                         begin
  48.                                 opcode_type = `TYPE_LD_Y;
  49.                                 opcode_rd   = instruction[8:4];
  50.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  51.                         end
  52.                         /* TODO 3: LDI */
  53.                         16'b1110_????_????_????:
  54.                         begin
  55.                                 opcode_type = `TYPE_LDI;
  56.                                 opcode_rd   = {1'b1, instruction[7:4]};
  57.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  58.                                 opcode_imd  = {4'b0, instruction[11:8], instruction[3:0]};
  59.                         end
  60.                         /* TODO 6,7: instructions */
  61.                         16'b1010_0???_????_????:
  62.                         begin
  63.                                 opcode_type = `TYPE_LDS;
  64.                                 opcode_rd   = {1'b1, instruction[7:4]};
  65.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  66.                                 opcode_imd  = {~instruction[8], instruction[8], instruction[10:9], instruction[3:0]};
  67.                         end
  68.                        
  69.                         16'b0010_11??_????_????:
  70.                         begin
  71.                                 opcode_type = `TYPE_MOV;
  72.                                 opcode_rd   = instruction[8:4];
  73.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  74.                         end
  75.                        
  76.                                 16'b1001_010?_????_0001: begin
  77.                                 opcode_type = `TYPE_NEG;
  78.                                 opcode_rd   = instruction[8:4];
  79.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  80.                         end
  81.                         16'b0000_0000_0000_0000: begin
  82.                                 opcode_type = `TYPE_NOP;
  83.                                 opcode_rd   = {R_ADDR_WIDTH{1'bx}};
  84.                                 opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  85.                         end
  86.                         16'b0010_10??_????_????: begin
  87.                                 opcode_type = `TYPE_OR;
  88.                                 opcode_rd   = instruction[8:4];
  89.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  90.                         end
  91.                         16'b0001_10??_????_????: begin
  92.                                 opcode_type = `TYPE_SUB;
  93.                                 opcode_rd   = instruction[8:4];
  94.                                 opcode_rr   = {instruction[9], instruction[3:0]};
  95.                         end
  96.                         /*TODO 4: STS */
  97.                         16'b1010_1???_????_????:
  98.                         begin
  99.                                 /* TODO : De codificat instructiunile din laborator. */
  100.                                 opcode_type = `TYPE_STS;
  101.                                 opcode_rd   = {R_ADDR_WIDTH{1'bx}};
  102.                                 opcode_rr   = {1'b1, instruction[7:4]};
  103.                                 opcode_imd  = {~instruction[8], instruction[8], instruction[10:9], instruction[3:0]};
  104.                         end
  105.                                 default: begin
  106.                                         opcode_type = `TYPE_UNKNOWN;
  107.                                         opcode_rd   = {R_ADDR_WIDTH{1'bx}};
  108.                                         opcode_rr   = {R_ADDR_WIDTH{1'bx}};
  109.                                 end
  110.                 /*TODO : completati cu opcodes ale voastre.
  111.                   Where can I find such opcodes? Make them up or read the lab and see
  112.                   they're at http://www.atmel.com/images/Atmel-0856-AVR-Instruction-Set-Manual.pdf  */
  113.                   /* Cand gasiti o instructiune de UAL, setati opcode_type la valoarea corecta */
  114.                   /*  instruction seamana cu un ADD? -> opcode_type = `TYPE_ADD; */
  115.                   endcase
  116.         end
  117.  
  118.         assign opcode_group[`GROUP_ALU_ONE_OP] =
  119.                 (opcode_type == `TYPE_NEG);
  120.         assign opcode_group[`GROUP_ALU_TWO_OP] =
  121.                 (opcode_type == `TYPE_ADD) ||
  122.                 (opcode_type == `TYPE_ADC) ||
  123.                 (opcode_type == `TYPE_SUB) ||
  124.                 (opcode_type == `TYPE_AND) ||
  125.                 (opcode_type == `TYPE_EOR) ||
  126.                 (opcode_type == `TYPE_OR);
  127.         assign opcode_group[`GROUP_ALU] =
  128.                 opcode_group[`GROUP_ALU_ONE_OP] ||
  129.                 opcode_group[`GROUP_ALU_TWO_OP];
  130.  
  131.         assign opcode_group[`GROUP_LOAD_DIRECT] =
  132.                 (opcode_type == `TYPE_LDS);
  133.         assign opcode_group[`GROUP_LOAD_INDIRECT] =
  134.                 (opcode_type == `TYPE_LD_Y);
  135.  
  136.         assign opcode_group[`GROUP_STORE_DIRECT] =
  137.                 (opcode_type == `TYPE_STS);
  138.         assign opcode_group[`GROUP_STORE_INDIRECT] =
  139.                 0;
  140.  
  141.         assign opcode_group[`GROUP_REGISTER] =
  142.                 /* TODO 3: LDI */
  143.                 (opcode_type == `TYPE_LDI) ||
  144.                 (opcode_type == `TYPE_MOV);
  145.  
  146.         assign opcode_group[`GROUP_LOAD] =
  147.                 opcode_group[`GROUP_LOAD_DIRECT] ||
  148.                 opcode_group[`GROUP_LOAD_INDIRECT];
  149.         assign opcode_group[`GROUP_STORE] =
  150.                 opcode_group[`GROUP_STORE_DIRECT] ||
  151.                 opcode_group[`GROUP_STORE_INDIRECT];
  152.         assign opcode_group[`GROUP_MEMORY] =
  153.                 (opcode_group[`GROUP_LOAD] ||
  154.                  opcode_group[`GROUP_STORE]);
  155. endmodule
  156.