Last active
November 29, 2017 08:01
-
-
Save tinyfpga/40a7fe52d56365ad7546d153b491f8a0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// reg_sel mux select | |
reg [1:0] reg_sel; | |
`define REG_SEL_RD 'h0 | |
`define REG_SEL_RS1 'h1 | |
`define REG_SEL_RS2 'h2 | |
`define REG_SEL_PC 'h3 | |
// alu_rhs_sel mux select | |
reg [1:0] alu_rhs_sel; | |
`define ALU_RHS_SEL_B 'h0 | |
`define ALU_RHS_SEL_4 'h1 | |
`define ALU_RHS_SEL_2 'h2 | |
`define ALU_RHS_SEL_1 'h3 | |
// alu_op mux select | |
reg [3:0] alu_op; | |
`define ALU_OP_ADD 'h0 | |
`define ALU_OP_SUB 'h1 | |
`define ALU_OP_SLT 'h2 | |
`define ALU_OP_SLTU 'h3 | |
`define ALU_OP_AND 'h4 | |
`define ALU_OP_OR 'h5 | |
`define ALU_OP_XOR 'h6 | |
`define ALU_OP_SLL 'h7 | |
`define ALU_OP_SRL 'h8 | |
`define ALU_OP_SRA 'h9 | |
// alu_cmp_op mux select | |
reg [2:0] alu_cmp_op; // reg_sel mux select | |
reg [1:0] reg_sel; | |
`define REG_SEL_RD 'h0 | |
`define REG_SEL_RS1 'h1 | |
`define REG_SEL_RS2 'h2 | |
`define REG_SEL_PC 'h3 | |
// alu_rhs_sel mux select | |
reg [1:0] alu_rhs_sel; | |
`define ALU_RHS_SEL_B 'h0 | |
`define ALU_RHS_SEL_4 'h1 | |
`define ALU_RHS_SEL_2 'h2 | |
`define ALU_RHS_SEL_1 'h3 | |
// alu_op mux select | |
reg [3:0] alu_op; | |
`define ALU_OP_ADD 'h0 | |
`define ALU_OP_SUB 'h1 | |
`define ALU_OP_SLT 'h2 | |
`define ALU_OP_SLTU 'h3 | |
`define ALU_OP_AND 'h4 | |
`define ALU_OP_OR 'h5 | |
`define ALU_OP_XOR 'h6 | |
`define ALU_OP_SLL 'h7 | |
`define ALU_OP_SRL 'h8 | |
`define ALU_OP_SRA 'h9 | |
// alu_cmp_op mux select | |
reg [2:0] alu_cmp_op; | |
`define ALU_CMP_OP_EQ 'h0 | |
`define ALU_CMP_OP_NE 'h1 | |
`define ALU_CMP_OP_LT 'h2 | |
`define ALU_CMP_OP_GE 'h3 | |
`define ALU_CMP_OP_LTU 'h4 | |
`define ALU_CMP_OP_GEU 'h5 | |
// imm_sel mux select | |
reg [2:0] imm_sel; | |
`define IMM_SEL_I_IMM 'h0 | |
`define IMM_SEL_S_IMM 'h1 | |
`define IMM_SEL_B_IMM 'h2 | |
`define IMM_SEL_U_IMM 'h3 | |
`define IMM_SEL_J_IMM 'h4 | |
// branch_target mux select | |
reg [5:0] branch_target; | |
`define BRANCH_TARGET_RESET 'h0 | |
`define BRANCH_TARGET_FETCH 'h1 | |
`define BRANCH_TARGET_ALUI 'h5 | |
`define BRANCH_TARGET_ALU 'h9 | |
`define BRANCH_TARGET_LUI 'hd | |
`define BRANCH_TARGET_AUIPC 'hf | |
`define BRANCH_TARGET_LOAD 'h12 | |
`define BRANCH_TARGET_STORE 'h16 | |
`define BRANCH_TARGET_JAL 'h1a | |
`define BRANCH_TARGET_JALR 'h1e | |
`define BRANCH_TARGET_BR 'h23 | |
`define BRANCH_TARGET_BR_TAKEN 'h2a | |
// ir_dispatch decode table | |
reg [5:0] ir_dispatch_dec_tab; | |
always @* | |
casez (ir) | |
32'b?????????????????????????0010011: ir_dispatch_dec_tab <= IR_DISPATCH_ALUI; | |
32'b?????????????????????????0110111: ir_dispatch_dec_tab <= IR_DISPATCH_LUI; | |
32'b?????????????????????????0010111: ir_dispatch_dec_tab <= IR_DISPATCH_AUIPC; | |
32'b?????????????????????????0110011: ir_dispatch_dec_tab <= IR_DISPATCH_ALU; | |
32'b?????????????????????????1101111: ir_dispatch_dec_tab <= IR_DISPATCH_JAL; | |
32'b?????????????????????????1100111: ir_dispatch_dec_tab <= IR_DISPATCH_JALR; | |
32'b?????????????????????????1100011: ir_dispatch_dec_tab <= IR_DISPATCH_BR; | |
32'b?????????????????????????0000011: ir_dispatch_dec_tab <= IR_DISPATCH_LOAD; | |
32'b?????????????????????????0100011: ir_dispatch_dec_tab <= IR_DISPATCH_STORE; | |
default: ir_dispatch_dec_tab <= 6'bxxxxxx; | |
endcase | |
// op decode table | |
reg [3:0] op_dec_tab; | |
always @* | |
casez (ir) | |
32'b?????????????????000??????0?????: op_dec_tab <= OP_ADD; | |
32'b?0???????????????000??????1?????: op_dec_tab <= OP_ADD; | |
32'b?1???????????????000??????1?????: op_dec_tab <= OP_SUB; | |
32'b?????????????????010????????????: op_dec_tab <= OP_SLT; | |
32'b?????????????????011????????????: op_dec_tab <= OP_SLTU; | |
32'b?????????????????111????????????: op_dec_tab <= OP_AND; | |
32'b?????????????????110????????????: op_dec_tab <= OP_OR; | |
32'b?????????????????100????????????: op_dec_tab <= OP_XOR; | |
32'b?????????????????001????????????: op_dec_tab <= OP_SLL; | |
32'b?0???????????????101????????????: op_dec_tab <= OP_SRL; | |
32'b?1???????????????101????????????: op_dec_tab <= OP_SRA; | |
default: op_dec_tab <= 4'bxxxx; | |
endcase | |
// cmp decode table | |
reg [2:0] cmp_dec_tab; | |
always @* | |
casez (ir) | |
32'b?????????????????000????????????: cmp_dec_tab <= CMP_EQ; | |
32'b?????????????????001????????????: cmp_dec_tab <= CMP_NE; | |
32'b?????????????????100????????????: cmp_dec_tab <= CMP_LT; | |
32'b?????????????????101????????????: cmp_dec_tab <= CMP_GE; | |
32'b?????????????????110????????????: cmp_dec_tab <= CMP_LTU; | |
32'b?????????????????111????????????: cmp_dec_tab <= CMP_GEU; | |
default: cmp_dec_tab <= 3'bxxx; | |
endcase | |
// ucode rom | |
reg [5:0] uip; | |
reg [39:0] ucode_rom_out; | |
always @(posedge clk) | |
case (uip) | |
// reset | |
6'h000: ucode_rom_out <= 40'b0000001011100000000000000000000000000000; // reg[pc] <= addr_rst {'reg_sel': 'pc', 'en_addr_rst': 1, 'reg_wr': 1} | |
// fetch | |
6'h001: ucode_rom_out <= 40'b0000000011000000000000000000000000000100; // reg_out <= reg[pc] {'reg_sel': 'pc', 'reg_rd': 1} | |
6'h002: ucode_rom_out <= 40'b0100000000000000000000000001000100000000; // ma <= reg_out; a <= reg_out {'ld_a': 1, 'en_reg': 1, 'ld_ma': 1} | |
6'h003: ucode_rom_out <= 40'b0000000100000000010000100000000000001011; // ir <= mem; goto %IR_DISPATCH {'en_mem': 1, 'ir_dispatch_dec_tab_en': 1, 'branch': 1, 'ld_ir': 1, 'wait_until_mem_ready': 1, 'branch_target': '%IR_DISPATCH', 'mem_read': 1} | |
6'h004: ucode_rom_out <= 40'b0000100011100000000000000000000001010000; // reg[pc] <= a ADD 4 {'reg_sel': 'pc', 'alu_rhs_sel': '4', 'alu_op': 'ADD', 'reg_wr': 1, 'en_alu': 1, 'wait_until_alu_valid': 1} | |
// alui | |
6'h005: ucode_rom_out <= 40'b0000000001000000000000000000000000000100; // reg_out <= reg[rs1] {'reg_sel': 'rs1', 'reg_rd': 1} | |
6'h006: ucode_rom_out <= 40'b0100000000000000000000000000000100000000; // a <= reg_out {'ld_a': 1, 'en_reg': 1} | |
6'h007: ucode_rom_out <= 40'b0011000100000000100000000000000000000000; // b <= imm[i_imm]; goto fetch {'branch_target': 'fetch', 'ld_b': 1, 'imm_sel': 'i_imm', 'branch': 1, 'en_imm': 1} | |
6'h008: ucode_rom_out <= 40'b0000110000100000000000000000000000010000; // reg[rd] <= a %OP b {'reg_sel': 'rd', 'alu_rhs_sel': 'b', 'alu_op': '%OP', 'reg_wr': 1, 'en_alu': 1, 'wait_until_alu_valid': 1, 'op_dec_tab_en': 1} | |
// alu | |
6'h009: ucode_rom_out <= 40'b0000000001000000000000000000000000000100; // reg_out <= reg[rs1] {'reg_sel': 'rs1', 'reg_rd': 1} | |
6'h00a: ucode_rom_out <= 40'b0100000010000000000000000000000100000100; // a <= reg_out; reg_out <= reg[rs2] {'ld_a': 1, 'reg_sel': 'rs2', 'en_reg': 1, 'reg_rd': 1} | |
6'h00b: ucode_rom_out <= 40'b0010000100000000100000000000000100000000; // b <= reg_out; goto fetch {'ld_b': 1, 'en_reg': 1, 'branch_target': 'fetch', 'branch': 1} | |
6'h00c: ucode_rom_out <= 40'b0000110000100000000000000000000000010000; // reg[rd] <= a %OP b {'reg_sel': 'rd', 'alu_rhs_sel': 'b', 'alu_op': '%OP', 'reg_wr': 1, 'en_alu': 1, 'wait_until_alu_valid': 1, 'op_dec_tab_en': 1} | |
// lui | |
6'h00d: ucode_rom_out <= 40'b0001000100100000100000000000011000000000; // reg[rd] <= imm[u_imm]; goto fetch {'imm_sel': 'u_imm', 'branch': 1, 'reg_sel': 'rd', 'reg_wr': 1, 'branch_target': 'fetch', 'en_imm': 1} | |
6'h00e: ucode_rom_out <= 40'b0000000000000000000000000000000000000000; // nop {} | |
// auipc | |
6'h00f: ucode_rom_out <= 40'b0011000011000000000000000000011000000100; // b <= imm[u_imm]; reg_out <= reg[pc] {'reg_sel': 'pc', 'reg_rd': 1, 'ld_b': 1, 'imm_sel': 'u_imm', 'en_imm': 1} | |
6'h010: ucode_rom_out <= 40'b0100000100000000100000000000000100000000; // a <= reg_out; goto fetch {'ld_a': 1, 'en_reg': 1, 'branch_target': 'fetch', 'branch': 1} | |
6'h011: ucode_rom_out <= 40'b0000100000100000000000000000000000010000; // reg[rd] <= a ADD b {'reg_sel': 'rd', 'alu_rhs_sel': 'b', 'alu_op': 'ADD', 'reg_wr': 1, 'en_alu': 1, 'wait_until_alu_valid': 1} | |
// load | |
6'h012: ucode_rom_out <= 40'b0011000001000000000000000000000000000100; // b <= imm[i_imm]; reg_out <= reg[rs1] {'reg_sel': 'rs1', 'reg_rd': 1, 'ld_b': 1, 'imm_sel': 'i_imm', 'en_imm': 1} | |
6'h013: ucode_rom_out <= 40'b0100000000000000000000000000000100000000; // a <= reg_out {'ld_a': 1, 'en_reg': 1} | |
6'h014: ucode_rom_out <= 40'b0000100100000000100000000001000000010000; // ma <= a ADD b; goto fetch {'ld_ma': 1, 'branch': 1, 'alu_rhs_sel': 'b', 'alu_op': 'ADD', 'en_alu': 1, 'wait_until_alu_valid': 1, 'branch_target': 'fetch'} | |
6'h015: ucode_rom_out <= 40'b0000000000100000010000000000000000001010; // reg[rd] <= mem {'reg_sel': 'rd', 'en_mem': 1, 'reg_wr': 1, 'wait_until_mem_ready': 1, 'mem_read': 1} | |
// store | |
6'h016: ucode_rom_out <= 40'b0011000001000000000000000000001000000100; // b <= imm[s_imm]; reg_out <= reg[rs1] {'reg_sel': 'rs1', 'reg_rd': 1, 'ld_b': 1, 'imm_sel': 's_imm', 'en_imm': 1} | |
6'h017: ucode_rom_out <= 40'b0100000010000000000000000000000100000100; // a <= reg_out; reg_out <= reg[rs2] {'ld_a': 1, 'reg_sel': 'rs2', 'en_reg': 1, 'reg_rd': 1} | |
6'h018: ucode_rom_out <= 40'b0000100100000000100000000001000000010000; // ma <= a ADD b; goto fetch {'ld_ma': 1, 'branch': 1, 'alu_rhs_sel': 'b', 'alu_op': 'ADD', 'en_alu': 1, 'wait_until_alu_valid': 1, 'branch_target': 'fetch'} | |
6'h019: ucode_rom_out <= 40'b0000000000000000000000010000000100000000; // mem <= reg_out {'en_reg': 1, 'mem_write': 1} | |
// jal | |
6'h01a: ucode_rom_out <= 40'b0011000011000000000000000000100000000100; // b <= imm[j_imm]; reg_out <= reg[pc] {'reg_sel': 'pc', 'reg_rd': 1, 'ld_b': 1, 'imm_sel': 'j_imm', 'en_imm': 1} | |
6'h01b: ucode_rom_out <= 40'b0100000000100000000000000000000100000000; // a <= reg_out; reg[rd] <= reg_out {'ld_a': 1, 'reg_sel': 'rd', 'reg_wr': 1, 'en_reg': 1} | |
6'h01c: ucode_rom_out <= 40'b0100100100000000100001000000000001010000; // a <= a SUB 4; goto fetch {'ld_a': 1, 'branch': 1, 'alu_rhs_sel': '4', 'alu_op': 'SUB', 'en_alu': 1, 'wait_until_alu_valid': 1, 'branch_target': 'fetch'} | |
6'h01d: ucode_rom_out <= 40'b0000100011100000000000000000000000010000; // reg[pc] <= a ADD b {'reg_sel': 'pc', 'alu_rhs_sel': 'b', 'alu_op': 'ADD', 'reg_wr': 1, 'en_alu': 1, 'wait_until_alu_valid': 1} | |
// jalr | |
6'h01e: ucode_rom_out <= 40'b0011000011000000000000000000000000000100; // b <= imm[i_imm]; reg_out <= reg[pc] {'reg_sel': 'pc', 'reg_rd': 1, 'ld_b': 1, 'imm_sel': 'i_imm', 'en_imm': 1} | |
6'h01f: ucode_rom_out <= 40'b0000000000100000000000000000000100000000; // reg[rd] <= reg_out {'reg_sel': 'rd', 'en_reg': 1, 'reg_wr': 1} | |
6'h020: ucode_rom_out <= 40'b0000000001000000000000000000000000000100; // reg_out <= reg[rs1] {'reg_sel': 'rs1', 'reg_rd': 1} | |
6'h021: ucode_rom_out <= 40'b0100000100000000100000000000000100000000; // a <= reg_out; goto fetch {'ld_a': 1, 'en_reg': 1, 'branch_target': 'fetch', 'branch': 1} | |
6'h022: ucode_rom_out <= 40'b0000100011100000000000000000000000010000; // reg[pc] <= a ADD b {'reg_sel': 'pc', 'alu_rhs_sel': 'b', 'alu_op': 'ADD', 'reg_wr': 1, 'en_alu': 1, 'wait_until_alu_valid': 1} | |
// br | |
6'h023: ucode_rom_out <= 40'b0000000001000000000000000000000000000100; // reg_out <= reg[rs1] {'reg_sel': 'rs1', 'reg_rd': 1} | |
6'h024: ucode_rom_out <= 40'b0100000010000000000000000000000100000100; // a <= reg_out; reg_out <= reg[rs2] {'ld_a': 1, 'reg_sel': 'rs2', 'en_reg': 1, 'reg_rd': 1} | |
6'h025: ucode_rom_out <= 40'b0010000011000000000000000000000100000100; // b <= reg_out; reg_out <= reg[pc] {'reg_sel': 'pc', 'ld_b': 1, 'en_reg': 1, 'reg_rd': 1} | |
6'h026: ucode_rom_out <= 40'b1011000000010101000000000000010000110000; // if a %CMP b then goto br_taken; b <= imm[b_imm] {'branch_if_alu_true': 1, 'en_imm': 1, 'imm_sel': 'b_imm', 'alu_rhs_sel': 'b', 'cmp_dec_tab_en': 1, 'ld_b': 1, 'wait_until_alu_valid': 1, 'branch_target': 'br_taken', 'alu_cmp_op': '%CMP'} | |
6'h027: ucode_rom_out <= 40'b0100000000000000000000000000000100000000; // a <= reg_out {'ld_a': 1, 'en_reg': 1} | |
6'h028: ucode_rom_out <= 40'b0000000100000000100000000000000000000000; // goto fetch {'branch_target': 'fetch', 'branch': 1} | |
6'h029: ucode_rom_out <= 40'b0000000000000000000000000000000000000000; // nop {} | |
// br_taken | |
6'h02a: ucode_rom_out <= 40'b0100100100000000100001000000000001010000; // a <= a SUB 4; goto fetch {'ld_a': 1, 'branch': 1, 'alu_rhs_sel': '4', 'alu_op': 'SUB', 'en_alu': 1, 'wait_until_alu_valid': 1, 'branch_target': 'fetch'} | |
6'h02b: ucode_rom_out <= 40'b0000100011100000000000000000000000010000; // reg[pc] <= a ADD b {'reg_sel': 'pc', 'alu_rhs_sel': 'b', 'alu_op': 'ADD', 'reg_wr': 1, 'en_alu': 1, 'wait_until_alu_valid': 1} | |
default: ucode_rom_out <= 40'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; | |
endcase |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment