Skip to content

Instantly share code, notes, and snippets.

@tinyfpga
Last active November 29, 2017 08:01
Show Gist options
  • Save tinyfpga/40a7fe52d56365ad7546d153b491f8a0 to your computer and use it in GitHub Desktop.
Save tinyfpga/40a7fe52d56365ad7546d153b491f8a0 to your computer and use it in GitHub Desktop.
// 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