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