diff --git a/examples/hdl4se_riscv/de2/de2_riscv_v3.qws b/examples/hdl4se_riscv/de2/de2_riscv_v3.qws index 63563b76eda4b19c3f4f321afd3f1b7df67b8d5e..2734e4bdf9b644cb0e38de661c4a5e8dcbdf58be 100644 Binary files a/examples/hdl4se_riscv/de2/de2_riscv_v3.qws and b/examples/hdl4se_riscv/de2/de2_riscv_v3.qws differ diff --git a/examples/hdl4se_riscv/de2/de2_riscv_v3.sof b/examples/hdl4se_riscv/de2/de2_riscv_v3.sof new file mode 100644 index 0000000000000000000000000000000000000000..5f4615b65ec4bb84cf26363642f53bd36ae44037 Binary files /dev/null and b/examples/hdl4se_riscv/de2/de2_riscv_v3.sof differ diff --git a/examples/hdl4se_riscv/de2/de2_riscv_v4.qsf b/examples/hdl4se_riscv/de2/de2_riscv_v4.qsf index 68221818c50ca35809ba2acb60e2270e70dafbb7..b2f54d311164869b85753d3f5b88e1d2214559a2 100644 --- a/examples/hdl4se_riscv/de2/de2_riscv_v4.qsf +++ b/examples/hdl4se_riscv/de2/de2_riscv_v4.qsf @@ -993,6 +993,7 @@ set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name VERILOG_FILE ../verilog/altera/regfile/regfile.v set_global_assignment -name VERILOG_FILE qsys/pllqsys/synthesis/submodules/pllqsys_altpll_0.v set_global_assignment -name VERILOG_FILE qsys/pllqsys/synthesis/pllqsys.v set_global_assignment -name VERILOG_FILE ../verilog/riscv_core_v4.v diff --git a/examples/hdl4se_riscv/de2/de2_riscv_v4.qws b/examples/hdl4se_riscv/de2/de2_riscv_v4.qws deleted file mode 100644 index e70bde81efe1ec574ca95ed27b2c4f67ceb758e7..0000000000000000000000000000000000000000 Binary files a/examples/hdl4se_riscv/de2/de2_riscv_v4.qws and /dev/null differ diff --git a/examples/hdl4se_riscv/de2/de2_riscv_v4.sof b/examples/hdl4se_riscv/de2/de2_riscv_v4.sof index 23103723d05b24e5f2b818ef37ab2accabc2afb8..b896d40c3a6661caa1c700223575b1a79f4ca94a 100644 Binary files a/examples/hdl4se_riscv/de2/de2_riscv_v4.sof and b/examples/hdl4se_riscv/de2/de2_riscv_v4.sof differ diff --git a/examples/hdl4se_riscv/de2/de2_riscv_v4.v b/examples/hdl4se_riscv/de2/de2_riscv_v4.v index 9f4d35e676c21cc645781b3f646181cee9f8d63d..22634d9424e698fd8b360cce01717e7b65061bad 100644 --- a/examples/hdl4se_riscv/de2/de2_riscv_v4.v +++ b/examples/hdl4se_riscv/de2/de2_riscv_v4.v @@ -2,8 +2,8 @@ //======================================================= // This code is generated by Terasic System Builder //======================================================= -`define USECLOCK50_1 +`define USECLOCK50 module de2_riscv_v4( //////////// CLOCK ////////// @@ -365,7 +365,6 @@ output FL_WP_N; inout [35:0] GPIO; - wire uart_tx; wire uart_rx; assign GPIO[5] = uart_tx; @@ -374,18 +373,20 @@ inout [35:0] GPIO; assign LEDR[0] = uart_tx; assign LEDR[1] = uart_rx; - wire nwReset = KEY[3]; `ifdef USECLOCK50 wire wClk = CLOCK_50; `else wire clk100MHz, clk75MHz, clklocked; - pllqsys clk100(.clk_clk(CLOCK_50), - .reset_reset_n(~KEY[3]), - .altpll_0_c0_clk(clk100MHz)); + clk100M clk100(.refclk(CLOCK_50), + .rst(~KEY[3]), + .outclk_0(clk100MHz), + .outclk_1(clk75MHz), + .locked(clklocked)); wire wClk = clk100MHz; `endif + wire nwReset = KEY[3]; wire wWrite, wRead; wire [31:0] bWriteAddr, bWriteData, bReadAddr, bReadData, bReadDataRam, bReadDataKey, bReadDataUart; @@ -443,8 +444,21 @@ inout [35:0] GPIO; .sendfull(LEDR[4]), .recvempty(LEDR[5]) ); + + reg [4:0] lastregno; + reg [4:0] lastregno2; + + always @(posedge wClk) begin + lastregno <= regno; + lastregno2 <= regno2; + end + + regfile regs(regno, regena, wClk, regwrdata, regwren, regrddata); + regfile regs2(regno2, regena2, wClk, regwrdata2, regwren2, regrddata2); ram16kB ram(ramaddr, ~bWriteMask, wClk, bWriteData, ((bWriteAddr & 32'hff000000) == 0)?wWrite:1'b0, bReadDataRam); - riscv_core core(wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask, wRead, bReadAddr, bReadData + riscv_core core(wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask, wRead, bReadAddr, bReadData, + regno, regena, regwrdata, regwren, (lastregno == 0) ? 0 : regrddata, + regno2, regena2, regwrdata2, regwren2, (lastregno2 == 0) ? 0 : regrddata2 ); diff --git a/examples/hdl4se_riscv/hdl4se_riscv_sim/CMakeLists.txt b/examples/hdl4se_riscv/hdl4se_riscv_sim/CMakeLists.txt index e981e85dda4078b7f4fa5bfeceb92668dd32d015..f3efb134b5c5e279d95d0f094fad97001f849be5 100644 --- a/examples/hdl4se_riscv/hdl4se_riscv_sim/CMakeLists.txt +++ b/examples/hdl4se_riscv/hdl4se_riscv_sim/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(riscv_sim_v4 "main_v4.c" "hdl4se_riscv_core_v4.c" "hdl4se_riscv_ram8k.c" + "hdl4se_riscv_regfile.c" ) add_executable(riscv_sim_v3 diff --git a/examples/hdl4se_riscv/hdl4se_riscv_sim/hdl4se_riscv_core_v4.c b/examples/hdl4se_riscv/hdl4se_riscv_sim/hdl4se_riscv_core_v4.c index 2ccc3ca9dc179bd2467372170b74a585f46aa468..ca3bcd989e1dc7398e8cf3edf70a277c40fafdc0 100644 --- a/examples/hdl4se_riscv/hdl4se_riscv_sim/hdl4se_riscv_core_v4.c +++ b/examples/hdl4se_riscv/hdl4se_riscv_sim/hdl4se_riscv_core_v4.c @@ -53,91 +53,59 @@ #define M_ID(id) riscv_core##id IDLIST - VID(wClk), - VID(nwReset), - VID(wWrite), - VID(bWriteAddr), - VID(bWriteData), - VID(bWriteMask), - VID(wRead), - VID(bReadAddr), - VID(bReadData), - VID(pc), - VID(instr), - VID(write), - VID(writeaddr), - VID(writedata), - VID(writemask), - VID(readreg), - VID(state), - VID(imm), - VID(dstreg), - VID(dstvalue), - VID(ldaddr), - VID(divclk), - VID(rs1), - VID(rs2), - VID(cur_instr), - VID(rs1_no), - VID(rs2_no), - VID(opcode), - VID(rd), - VID(func3), - VID(rd_r), - VID(func3_r), - VID(cond), - VID(newpc), - VID(x1), - VID(x2), - VID(x3), - VID(x4), - VID(x5), - VID(x6), - VID(x7), - VID(x8), - VID(x9), - VID(x10), - VID(x11), - VID(x12), - VID(x13), - VID(x14), - VID(x15), - VID(x16), - VID(x17), - VID(x18), - VID(x19), - VID(x20), - VID(x21), - VID(x22), - VID(x23), - VID(x24), - VID(x25), - VID(x26), - VID(x27), - VID(x28), - VID(x29), - VID(x30), - VID(x31), +VID(wClk), +VID(nwReset), +VID(wWrite), +VID(bWriteAddr), +VID(bWriteData), +VID(bWriteMask), +VID(wRead), +VID(bReadAddr), +VID(bReadData), +VID(regno), +VID(regena), +VID(regwrdata), +VID(regwren), +VID(regrddata), +VID(regno2), +VID(regena2), +VID(regwrdata2), +VID(regwren2), +VID(regrddata2), +VID(pc), +VID(instr), +VID(write), +VID(writeaddr), +VID(writedata), +VID(writemask), +VID(readreg), +VID(state), +VID(imm), +VID(dstreg), +VID(dstvalue), +VID(lastv), +VID(lastaddr), +VID(ldaddr), +VID(divclk), END_IDLIST enum riscv_core_state { - RISCVSTATE_STARTUP, - RISCVSTATE_EXEC_INST, - RISCVSTATE_WAIT_LD, - RISCVSTATE_WAIT_ST, - RISCVSTATE_WAIT_DIV, + RISCVSTATE_INIT_REGX1, + RISCVSTATE_INIT_REGX2, + RISCVSTATE_READ_INST, + RISCVSTATE_READ_REGS, + RISCVSTATE_EXEC_INST, + RISCVSTATE_WRITE_RD, + RISCVSTATE_WAIT_LD, + RISCVSTATE_WAIT_LD2, + RISCVSTATE_WAIT_ST, + RISCVSTATE_WAIT_ST2, + RISCVSTATE_WAIT_DIV }; MODULE_DECLARE(riscv_core) END_MODULE_DECLARE(riscv_core) -FILE* recordfileGet(); - -#define DEBUG_CODE_FUNC fprintf(recordfileGet(), "%30s: %08x: %08x\n", __FUNCTION__, vget(pc), vget(instr)) -#define DEBUG_CODE_DECODE fprintf(recordfileGet(), -#define INSTR_FORMAT_ERROR fprintf(recordfileGet(), "instruction format error, we support rv32im only: pc=%08x: %x\n", vget(pc), vget(instr)); - - static unsigned int sign_expand(unsigned int v, int bit) { int i; @@ -156,195 +124,480 @@ DEFINE_FUNC(riscv_core_wr_sig, "write, writeaddr, writedata, writemask") { VAssign(bWriteMask, writemask); } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_cur_instr, "bReadData") { - VAssign(cur_instr, bReadData); -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_reg_gen_instr, "bReadData") { - VAssign(instr, bReadData); -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_gen_rs1_no, "instr") { - vput(rs1_no, (vget(instr) >> 15) & 0x1f); -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_gen_rs2_no, "instr") { - vput(rs2_no, (vget(instr) >> 20) & 0x1f); -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_gen_opcode, "instr") { - vput(opcode, (vget(instr) >> 2) & 0x1f); -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_gen_rd, "instr") { - vput(rd, (vget(instr) >> 7) & 0x1f); -} END_DEFINE_FUNC +DEFINE_FUNC(riscv_core_read_sig, "state, pc, instr, bReadData, regrddata, regrddata2") { + unsigned int state; + state = vget(state); + vput(wRead, 0); + if (state == RISCVSTATE_READ_INST) { + vput(wRead, 1); + vput(bReadAddr, vget(pc)); + } + else if (state == RISCVSTATE_EXEC_INST) { + unsigned int instr; + instr = vget(instr); + if ((instr & 0x7f) == 0x03) { + /* ld inst */ + unsigned int imm; + unsigned int rs1 = vget(regrddata); + unsigned int rs2 = vget(regrddata2); + unsigned int rdaddr; + imm = instr >> 20; + imm = sign_expand(imm, 11); + rdaddr = rs1 + imm; + vput(wRead, 1); + vput(bReadAddr, rdaddr); + } + } + else if (state == RISCVSTATE_WAIT_LD) { + unsigned int instr = vget(instr); + unsigned int func3 = (instr >> 12) & 0x7; + unsigned int ldaddr = vget(ldaddr); + if (func3 == 1 && (ldaddr & 3) == 3) { /* lh */ + vput(wRead, 1); + vput(bReadAddr, ldaddr + 4); + } + else if (func3 == 2 && (ldaddr & 3) != 0) { /* lw */ + vput(wRead, 1); + vput(bReadAddr, ldaddr + 4); -DEFINE_FUNC(riscv_core_gen_func3, "instr") { - vput(func3, (vget(instr) >> 12) & 0x7); + } + else if (func3 == 5 && (ldaddr & 3) == 3) { /* lhu */ + vput(wRead, 1); + vput(bReadAddr, ldaddr + 4); + } + else { + vput(wRead, 0); + vput(bReadAddr, 0); + } + } } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_rd_r, "cur_instr") { - vput(rd_r, (vget(cur_instr) >> 7) & 0x1f); +DEFINE_FUNC(riscv_core_gen_ldaddr, "state, pc, instr, regrddata") { + unsigned int state; + state = vget(state); + if (state == RISCVSTATE_READ_INST) { + vput(ldaddr, vget(pc)); + } + else if (state == RISCVSTATE_EXEC_INST) { + unsigned int instr; + instr = vget(instr); + if ((instr & 0x7f) == 0x03) { + /* ld inst */ + unsigned int imm; + unsigned int rs1; + unsigned int rdaddr; + imm = instr >> 20; + rs1 = vget(regrddata); + imm = sign_expand(imm, 11); + rdaddr = rs1 + imm; + vput(ldaddr, rdaddr); + if (rdaddr & 3) { + unsigned int func3 = (instr >> 12) & 0x7; + if (func3 == 2) { + printf("read a unaligned addr %08x, %08x, %d, %08x, %08x\n", vget(pc), instr, rdaddr & 3, rs1, imm); + } + } + } + } } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_func3_r, "cur_instr") { - vput(func3_r, (vget(cur_instr) >> 12) & 0x7); -} END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_rs1, - "rs1_no, " - "x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, " - "x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, " - "x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31" -) { - switch (vget(rs1_no)) { - case 0: vput(rs1, 0); break; - case 1: VAssign(rs1, x1); break; - case 2: VAssign(rs1, x2); break; - case 3: VAssign(rs1, x3); break; - case 4: VAssign(rs1, x4); break; - case 5: VAssign(rs1, x5); break; - case 6: VAssign(rs1, x6); break; - case 7: VAssign(rs1, x7); break; - case 8: VAssign(rs1, x8); break; - case 9: VAssign(rs1, x9); break; - case 10: VAssign(rs1, x10); break; - case 11: VAssign(rs1, x11); break; - case 12: VAssign(rs1, x12); break; - case 13: VAssign(rs1, x13); break; - case 14: VAssign(rs1, x14); break; - case 15: VAssign(rs1, x15); break; - case 16: VAssign(rs1, x16); break; - case 17: VAssign(rs1, x17); break; - case 18: VAssign(rs1, x18); break; - case 19: VAssign(rs1, x19); break; - case 20: VAssign(rs1, x20); break; - case 21: VAssign(rs1, x21); break; - case 22: VAssign(rs1, x22); break; - case 23: VAssign(rs1, x23); break; - case 24: VAssign(rs1, x24); break; - case 25: VAssign(rs1, x25); break; - case 26: VAssign(rs1, x26); break; - case 27: VAssign(rs1, x27); break; - case 28: VAssign(rs1, x28); break; - case 29: VAssign(rs1, x29); break; - case 30: VAssign(rs1, x30); break; - case 31: VAssign(rs1, x31); break; +DEFINE_FUNC(riscv_core_reg_wr_sig, "state, dstreg, dstvalue, bReadData, instr, regrddata, regrddata2, pc") { + unsigned int state = vget(state); + switch (state) { + case RISCVSTATE_READ_REGS: { + unsigned int instr = vget(bReadData); + vput(regno, (instr >> 15) & 0x1f); + vput(regwren, 0); + vput(regena, 0x0); + vput(regwrdata, 0x0); + vput(regno2, (instr >> 20) & 0x1f); + vput(regwren2, 0); + vput(regena2, 0x0); + vput(regwrdata2, 0x0); + }break; + case RISCVSTATE_WRITE_RD: { + unsigned int dstreg; + dstreg = vget(dstreg); + vput(regwren, (dstreg != 0) ? 1 : 0); + vput(regno, dstreg); + vput(regena, 0xf); + vput(regwrdata, vget(dstvalue)); + vput(regwren2, (dstreg != 0) ? 1 : 0); + vput(regno2, dstreg); + vput(regena2, 0xf); + vput(regwrdata2, vget(dstvalue)); + }break; + case RISCVSTATE_INIT_REGX1: { + vput(regwren, 1); + vput(regno, 1); + vput(regena, 0xf); + vput(regwrdata, 0x8c); + vput(regwren2, 1); + vput(regno2, 1); + vput(regena2, 0xf); + vput(regwrdata2, 0x8c); + }break; + case RISCVSTATE_INIT_REGX2: { + vput(regwren, 1); + vput(regno, 2); + vput(regena, 0xf); + vput(regwrdata, RAMSIZE * 4 - 16); + vput(regwren2, 1); + vput(regno2, 2); + vput(regena2, 0xf); + vput(regwrdata2, RAMSIZE * 4 - 16); + }break; + default: { + vput(regwren, 0); + vput(regno, 0); + vput(regena, 0x0); + vput(regwrdata, 0x0); + vput(regwren2, 0); + vput(regno2, 0); + vput(regena2, 0x0); + vput(regwrdata2, 0x0); + } } } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_rs2, - "rs2_no, " - "x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, " - "x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, " - "x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31" -) { - switch (vget(rs2_no)) { - case 0: vput(rs2, 0); break; - case 1: VAssign(rs2, x1); break; - case 2: VAssign(rs2, x2); break; - case 3: VAssign(rs2, x3); break; - case 4: VAssign(rs2, x4); break; - case 5: VAssign(rs2, x5); break; - case 6: VAssign(rs2, x6); break; - case 7: VAssign(rs2, x7); break; - case 8: VAssign(rs2, x8); break; - case 9: VAssign(rs2, x9); break; - case 10: VAssign(rs2, x10); break; - case 11: VAssign(rs2, x11); break; - case 12: VAssign(rs2, x12); break; - case 13: VAssign(rs2, x13); break; - case 14: VAssign(rs2, x14); break; - case 15: VAssign(rs2, x15); break; - case 16: VAssign(rs2, x16); break; - case 17: VAssign(rs2, x17); break; - case 18: VAssign(rs2, x18); break; - case 19: VAssign(rs2, x19); break; - case 20: VAssign(rs2, x20); break; - case 21: VAssign(rs2, x21); break; - case 22: VAssign(rs2, x22); break; - case 23: VAssign(rs2, x23); break; - case 24: VAssign(rs2, x24); break; - case 25: VAssign(rs2, x25); break; - case 26: VAssign(rs2, x26); break; - case 27: VAssign(rs2, x27); break; - case 28: VAssign(rs2, x28); break; - case 29: VAssign(rs2, x29); break; - case 30: VAssign(rs2, x30); break; - case 31: VAssign(rs2, x31); break; +FILE* recordfileGet(); + +#define DEBUG_CODE_FUNC fprintf(recordfileGet(), "%30s: %08x: %08x\n", __FUNCTION__, pc, instr) +#define DEBUG_CODE_DECODE fprintf(recordfileGet(), +#define INSTR_FORMAT_ERROR fprintf(recordfileGet(), "instruction format error, we support rv32im only: pc=%08x: %x\n", pc, instr); + +#define RISCV_SETDSTREG(rd, rst) \ +do { \ + vput(dstreg, rd); \ + vput(dstvalue, rst); \ +} while (0) + +void riscv_core_exec_alui_inst(MODULE_DATA_TYPE* pobj, unsigned int pc, unsigned int instr, unsigned int rs1, unsigned int rs2) { + /* addi, slti, sltiu, xori, ori, andi, slli, srli, srai */ + unsigned int imm; + unsigned int func3; + unsigned int rd; + func3 = (instr >> 12) & 0x7; + rd = (instr >> 7) & 0x1f; + imm = vget(imm); + switch (func3) { + case 0:/*addi*/ + RISCV_SETDSTREG(rd, rs1 + imm); + break; + case 1:/*slli*/ + RISCV_SETDSTREG(rd, rs1 << (imm & 0x1f)); + break; + case 2:/*slti*/ + RISCV_SETDSTREG(rd, (*(int*)&rs1 < *(int*)&imm) ? 1 : 0); + break; + case 3:/*sltiu*/ + RISCV_SETDSTREG(rd, rs1 < imm ? 1 : 0); + break; + case 4:/*xori*/ + RISCV_SETDSTREG(rd, rs1 ^ imm); + break; + case 5:/*srli/srai*/ + if (instr & (1 << 30)) + RISCV_SETDSTREG(rd, ((int)rs1) >> (imm & 0x1f)); + else + RISCV_SETDSTREG(rd, rs1 >> (imm & 0x1f)); + break; + case 6:/*ori*/ + RISCV_SETDSTREG(rd, rs1 | imm); + break; + case 7:/*andi*/ + RISCV_SETDSTREG(rd, rs1 & imm); + break; + default: + RISCV_SETDSTREG(0, 0); + DEBUG_CODE_FUNC; + break; } -} END_DEFINE_FUNC +} -DEFINE_FUNC(riscv_core_register, "dstreg, dstvalue, nwReset") { - if (vget(nwReset) == 0) { - vput(x1, 0x8c); - vput(x2, RAMSIZE * 4 - 16); +void riscv_core_exec_alu_inst(MODULE_DATA_TYPE* pobj, unsigned int pc, unsigned int instr, unsigned int rs1, unsigned int rs2) { + /* + add, sub, sll, slt, sltu, xor, srl, sra, or, and + mul, mulh, mulhsu, mulhu, div, divu, rem, remu + */ + unsigned int rd; + unsigned int func3; + unsigned int rst; + rst = 0; + func3 = (instr >> 12) & 0x7; + rd = (instr >> 7) & 0x1f; + if (instr & (1 << 25)) {/* is M instr*/ + switch (func3) { + case 0: { //mul + long long s1, s2; + s1 = *(int*)&rs1; + s2 = *(int*)&rs2; + s1 *= s2; + rst = *(unsigned int*)&s1; + }break; + case 1: { //mulh + long long s1, s2; + s1 = *(int*)&rs1; + s2 = *(int*)&rs2; + s1 *= s2; + rst = (*(unsigned long long*) & s1) >> 32; + }break; + case 2: { //mulhsu + long long s1, s2; + s1 = *(int*)&rs1; + s2 = rs2; + s1 *= s2; + rst = (*(unsigned long long*) & s1) >> 32; + }break; + case 3: { //mulhu + unsigned long long s1, s2; + s1 = rs1; + s2 = rs2; + s1 *= s2; + rst = s1 >> 32; + }break; +#if 1 + case 4: { //div + if (rs2 == 0) + rst = 0xffffffff; + else + *(int*)&rst = *(int*)&rs1 / *(int*)&rs2; + }break; + case 5: { //divu + if (rs2 == 0) + rst = 0xffffffff; + else + rst = rs1 / rs2; + }break; + case 6: { //rem + if (rs2 == 0) + rst = rs1; + else + *(int*)&rst = *(int*)&rs1 % *(int*)&rs2; + }break; + case 7: { //remu + if (rs2 == 0) + rst = rs1; + else + rst = rs1 % rs2; + }break; +#endif + } } else { - switch (vget(dstreg)) { - case 0: ; break; - case 1: VAssign(x1, dstvalue); break; - case 2: VAssign(x2, dstvalue); break; - case 3: VAssign(x3, dstvalue); break; - case 4: VAssign(x4, dstvalue); break; - case 5: VAssign(x5, dstvalue); break; - case 6: VAssign(x6, dstvalue); break; - case 7: VAssign(x7, dstvalue); break; - case 8: VAssign(x8, dstvalue); break; - case 9: VAssign(x9, dstvalue); break; - case 10: VAssign(x10, dstvalue); break; - case 11: VAssign(x11, dstvalue); break; - case 12: VAssign(x12, dstvalue); break; - case 13: VAssign(x13, dstvalue); break; - case 14: VAssign(x14, dstvalue); break; - case 15: VAssign(x15, dstvalue); break; - case 16: VAssign(x16, dstvalue); break; - case 17: VAssign(x17, dstvalue); break; - case 18: VAssign(x18, dstvalue); break; - case 19: VAssign(x19, dstvalue); break; - case 20: VAssign(x20, dstvalue); break; - case 21: VAssign(x21, dstvalue); break; - case 22: VAssign(x22, dstvalue); break; - case 23: VAssign(x23, dstvalue); break; - case 24: VAssign(x24, dstvalue); break; - case 25: VAssign(x25, dstvalue); break; - case 26: VAssign(x26, dstvalue); break; - case 27: VAssign(x27, dstvalue); break; - case 28: VAssign(x28, dstvalue); break; - case 29: VAssign(x29, dstvalue); break; - case 30: VAssign(x30, dstvalue); break; - case 31: VAssign(x31, dstvalue); break; + switch (func3) { + case 0: { //add/sub + if (instr & (1 << 30)) + rst = rs1 - rs2; + else + rst = rs1 + rs2; + }break; + case 1: { //sll + rst = rs1 << rs2; + }break; + case 2: { //slt + rst = (*(int*)&rs1 < *(int*)&rs2) ? 1 : 0; + }break; + case 3: { //sltu + rst = (rs1 < rs2) ? 1 : 0; + }break; + case 4: { //xor + rst = rs1 ^ rs2; + }break; + case 5: { //srl/sra + if (instr & (1 << 30)) + rst = rs1 >> rs2; + else + *(int*)&rst = (*(int*)&rs1) >> rs2; + }break; + case 6: { //or + rst = rs1 | rs2; + }break; + case 7: { //and + rst = rs1 & rs2; + }break; + } } -} END_DEFINE_FUNC + RISCV_SETDSTREG(rd, rst); +} -DEFINE_FUNC(riscv_core_gen_cond, "func3, rs1, rs2") { - unsigned int rs1, rs2; - rs1 = vget(rs1); - rs2 = vget(rs2); - switch (vget(func3)) { - case 0:/*beq*/ vput(cond, rs1 == rs2 ? 1 : 0); break; - case 1:/*bne*/ vput(cond, rs1 != rs2 ? 1 : 0); break; - case 4:/*blt*/ vput(cond, (*(int*)&rs1) < (*(int*)&rs2) ? 1 : 0); break; - case 5:/*bge*/ vput(cond, (*(int*)&rs1) >= (*(int*)&rs2) ? 1 : 0); break; - case 6:/*bltu*/vput(cond, rs1 < rs2 ? 1 : 0); break; - case 7:/*bgeu*/vput(cond, rs1 >= rs2 ? 1 : 0); break; - default: - vput(cond, 0); +void riscv_core_exec_fence_inst(MODULE_DATA_TYPE* pobj, unsigned int pc, unsigned int instr, unsigned int rs1, unsigned int rs2) { + /* fence, fence_i */ + DEBUG_CODE_FUNC; +} + +void riscv_core_exec_sys_inst(MODULE_DATA_TYPE* pobj, unsigned int pc, unsigned int instr, unsigned int rs1, unsigned int rs2) { + /* ecall, ebreak, csrrw, csrrs, csrrc, csrrwi, csrrsi, csrrci */ + DEBUG_CODE_FUNC; +} + +DEFINE_FUNC(riscv_core_exec_inst, "") { + unsigned int pc = vget(pc); + unsigned int instr = vget(instr); + unsigned int rs1 = vget(regrddata); + unsigned int rs2 = vget(regrddata2); + unsigned int opcode = instr & 0x7f; + if (((opcode & 0x3) != 3) || ((opcode >> 2) & 0x7) == 0x7) { + printf("instruction format error, we support 32bit instruction only: pc=%08x: %x", pc, instr); + exit(-2); + } + opcode >>= 2; + switch (opcode) { + case 0x0d: break;// riscv_core_exec_lui_inst(pobj, pc, instr, rs1, rs2); break; + case 0x05: break;// riscv_core_exec_auipc_inst(pobj, pc, instr, rs1, rs2); break; + case 0x1b: break;// riscv_core_exec_jal_inst(pobj, pc, instr, rs1, rs2); break; + case 0x19: break;// riscv_core_exec_jalr_inst(pobj, pc, instr, rs1, rs2); break; + case 0x18: break;// riscv_core_exec_b_inst(pobj, pc, instr, rs1, rs2); break; + case 0x00: break;// riscv_core_exec_ld_inst(pobj, pc, instr, rs1, rs2); break; + case 0x08: break;//riscv_core_exec_st_inst(pobj, pc, instr, rs1, rs2); break; + case 0x04: break;// riscv_core_exec_alui_inst(pobj, pc, instr, rs1, rs2); break; + case 0x0c: break;// riscv_core_exec_alu_inst(pobj, pc, instr, rs1, rs2); break; + case 0x03: riscv_core_exec_fence_inst(pobj, pc, instr, rs1, rs2); break; + case 0x1c: riscv_core_exec_sys_inst(pobj, pc, instr, rs1, rs2); break; + default: { INSTR_FORMAT_ERROR; exit(-2); - break; + } } } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_imm, "instr") { - unsigned int instr; - unsigned int opcode; - instr = vget(instr); - opcode = instr & 0x7f; - opcode >>= 2; - switch (opcode) { +DEFINE_FUNC(riscv_core_gen_dstreg, "state, instr, ldaddr, readreg, bReadData, pc, rs1, rs2, divclk, regrddata, imm") { + switch (vget(state)) { + case RISCVSTATE_INIT_REGX1: { + RISCV_SETDSTREG(1, 0x8c); + }break; + case RISCVSTATE_INIT_REGX2: { + RISCV_SETDSTREG(2, RAMSIZE * 4 - 16); + }break; + case RISCVSTATE_WAIT_LD: { + unsigned int instr = vget(instr); + unsigned int func3 = (instr >> 12) & 0x7; + unsigned int v; + unsigned int ldaddr = vget(ldaddr) & 3; + unsigned int readreg = vget(readreg); + v = vget(bReadData); + switch (func3) { + case 0:/*lb*/ + switch (ldaddr) { + case 0: v = (v >> 0) & 0xff; break; + case 1: v = (v >> 8) & 0xff; break; + case 2: v = (v >> 16) & 0xff; break; + case 3: v = (v >> 24) & 0xff; break; + } + v = sign_expand(v, 7); + RISCV_SETDSTREG(readreg, v); + break; + case 1:/*lh*/ + switch (ldaddr) { + case 0: v = (v >> 0) & 0xffff; break; + case 1: v = (v >> 8) & 0xffff; break; + case 2: v = (v >> 16) & 0xffff; break; + case 3: { + //printf("No support for load 16bit in more than one word[pc=%08x, instr=%08x, ldaddr=%d]\n", vget(pc), instr, ldaddr); + //exit(-8); + }break; + } + v = sign_expand(v, 15); + RISCV_SETDSTREG(readreg, v); + break; + case 2:/*lw*/ + if (ldaddr != 0) { + //printf("No support for load 32bit in more than one word[pc=%08x, instr=%08x, ldaddr=%d]\n", vget(pc), instr, ldaddr); + //exit(-9); + } + RISCV_SETDSTREG(readreg, v); + break; + case 4:/*lbu*/ + switch (ldaddr) { + case 0: v = (v >> 0) & 0xff; break; + case 1: v = (v >> 8) & 0xff; break; + case 2: v = (v >> 16) & 0xff; break; + case 3: v = (v >> 24) & 0xff; break; + } + RISCV_SETDSTREG(readreg, v); + break; + case 5:/*lhu*/ + switch (ldaddr) { + case 0: v = (v >> 0) & 0xffff; break; + case 1: v = (v >> 8) & 0xffff; break; + case 2: v = (v >> 16) & 0xffff; break; + case 3: { + //printf("No support for load 16bit in more than one word[pc=%08x, instr=%08x, ldaddr=%d]\n", vget(pc), instr, ldaddr); + //exit(-8); + }break; + } + RISCV_SETDSTREG(readreg, v); + break; + default: + RISCV_SETDSTREG(0, 0); + break; + } + }break; + case RISCVSTATE_WAIT_LD2: { + unsigned int instr = vget(instr); + unsigned int func3 = (instr >> 12) & 0x7; + unsigned int v; + unsigned int lastv = vget(lastv); + unsigned int ldaddr = vget(ldaddr) & 3; + unsigned int readreg = vget(readreg); + v = vget(bReadData); + if (func3 == 1 && ldaddr == 3) { + v = ((v << 8) & 0xff00) | lastv; + v = sign_expand(v, 15); + RISCV_SETDSTREG(readreg, v); + } + else if (func3 == 2 && ldaddr != 0) { + v = (v << ((4 - ldaddr) * 8)) | lastv; + RISCV_SETDSTREG(readreg, v); + } + else if (func3 == 5 && ldaddr == 3) { + v = ((v << 8) & 0xff00) | lastv; + RISCV_SETDSTREG(readreg, v); + } else { + RISCV_SETDSTREG(0, 0); + } + }break; + case RISCVSTATE_EXEC_INST: { + unsigned int pc = vget(pc); + unsigned int instr = vget(instr); + unsigned int rs1 = vget(regrddata); + unsigned int rs2 = vget(regrddata2); + unsigned int imm = vget(imm); + unsigned int opcode = instr & 0x7f; + unsigned int rd = (instr >> 7) & 0x1f; + opcode >>= 2; + switch (opcode) { + case 0x0d: RISCV_SETDSTREG(rd, imm); break; + case 0x05: RISCV_SETDSTREG(rd, imm + pc); break; + case 0x1b: RISCV_SETDSTREG(rd, pc + 4); break; + case 0x19: RISCV_SETDSTREG(rd, pc + 4); break; + case 0x04: riscv_core_exec_alui_inst(pobj, pc, instr, rs1, rs2); break; + case 0x0c: riscv_core_exec_alu_inst(pobj, pc, instr, rs1, rs2); break; + default: { + RISCV_SETDSTREG(0, 0); + } + } + } break; + case RISCVSTATE_WAIT_DIV: if (vget(divclk) == 0) { + + }break; + default: { + RISCV_SETDSTREG(0, 0); + }break; + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_imm, "instr, state") { + /* 在RISCVSTATE_READ_REGS周期生成imm */ + if (vget(state) == RISCVSTATE_READ_REGS) { + unsigned int instr; + unsigned int opcode; + instr = vget(bReadData); + opcode = instr & 0x7f; + opcode >>= 2; + switch (opcode) { case 0x0d: { vput(imm, instr & 0xfffff000); }break; @@ -398,466 +651,362 @@ DEFINE_FUNC(riscv_core_gen_imm, "instr") { imm = sign_expand(imm, 11); vput(imm, imm); }break; + } } } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_state, "state, instr, opcode, func3, rs2, nwReset") { +DEFINE_FUNC(riscv_core_gen_state, "state, instr, nwReset, imm, ldaddr, lastaddr, lastv") { if (vget(nwReset) == 0) { - vput(state, RISCVSTATE_STARTUP); + vput(state, RISCVSTATE_INIT_REGX1); } else { int state = vget(state); switch (state) { - case RISCVSTATE_STARTUP: { + case RISCVSTATE_INIT_REGX1: { + vput(state, RISCVSTATE_INIT_REGX2); + }break; + case RISCVSTATE_INIT_REGX2: { + vput(state, RISCVSTATE_READ_INST); + }break; + case RISCVSTATE_READ_INST: { + vput(state, RISCVSTATE_READ_REGS); + }break; + case RISCVSTATE_READ_REGS: { vput(state, RISCVSTATE_EXEC_INST); }break; + case RISCVSTATE_WRITE_RD: { + vput(state, RISCVSTATE_READ_INST); + }break; case RISCVSTATE_EXEC_INST: { unsigned int instr = vget(instr); - unsigned int opcode = vget(opcode); - unsigned int func3 = vget(func3); - unsigned int rs2 = vget(rs2); + unsigned int opcode = instr & 0x7f; + unsigned int func3 = (instr >> 12) & 0x7; + + opcode >>= 2; if (opcode == 0x00) vput(state, RISCVSTATE_WAIT_LD);//ld else if (opcode == 0x08) vput(state, RISCVSTATE_WAIT_ST);//st - /* else if (opcode == 0x0c && (instr & (1 << 25)) && (func3 & 4) && rs2 != 0) { + /* else if (opcode == 0x0c && (instr & (1 << 25)) && (func3 & 4)) { vput(state, RISCVSTATE_WAIT_DIV); }*/ + else + vput(state, RISCVSTATE_WRITE_RD); }break; case RISCVSTATE_WAIT_LD: { - vput(state, RISCVSTATE_EXEC_INST); + unsigned int instr = vget(instr); + unsigned int func3 = (instr >> 12) & 0x7; + unsigned int ldaddr = vget(ldaddr); + ldaddr &= 3; + if (func3 == 1 && ldaddr == 3) { /* lh */ + vput(state, RISCVSTATE_WAIT_LD2); + } + else if (func3 == 2 && ldaddr != 0) { /* lw */ + vput(state, RISCVSTATE_WAIT_LD2); + } + else if (func3 == 5 && ldaddr == 3) { /* lhu */ + vput(state, RISCVSTATE_WAIT_LD2); + } + else { + vput(state, RISCVSTATE_WRITE_RD); + } + }break; + case RISCVSTATE_WAIT_LD2: { + vput(state, RISCVSTATE_WRITE_RD); }break; case RISCVSTATE_WAIT_ST: { - vput(state, RISCVSTATE_EXEC_INST); + unsigned int instr = vget(instr); + unsigned int lastaddr = vget(lastaddr); + unsigned int opcode = instr & 0x7f; + unsigned int func3; + func3 = (instr >> 12) & 0x7; + opcode >>= 2; + vput(state, RISCVSTATE_READ_INST); + if (opcode == 0x08) { + if (func3 == 1 && (lastaddr & 3) == 3) { /* sh */ + vput(state, RISCVSTATE_WAIT_ST2); + } + else if (func3 == 2 && (lastaddr & 3) != 0) { + vput(state, RISCVSTATE_WAIT_ST2); + } + } }break; - /*case RISCVSTATE_WAIT_DIV: { + case RISCVSTATE_WAIT_ST2: { + vput(state, RISCVSTATE_READ_INST); + }break; + case RISCVSTATE_WAIT_DIV: { if (vget(divclk) == 0) - vput(state, RISCVSTATE_EXEC_INST); - }break;*/ - } - } -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_gen_newpc, "state, opcode, pc, imm, rs1, cond") { - if (vget(state) == RISCVSTATE_EXEC_INST) { - switch (vget(opcode)) { - case 0x1b: vput(newpc, vget(pc) + vget(imm)); break; - case 0x19: vput(newpc, vget(rs1) + vget(imm)); break; - case 0x18: vput(newpc, vget(cond) ? (vget(pc) + vget(imm)) : (vget(pc) + 4)); break; - default : vput(newpc, vget(pc) + 4); break; + vput(state, RISCVSTATE_WRITE_RD); + }break; } } - else { - VAssign(newpc, pc); - } -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_reg_gen_pc, "nwReset, newpc") { - if (vget(nwReset) == 0) { - vput(pc, 0x74); - } - else { - VAssign(pc, newpc); - } } END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_read_sig, "nwReset, state, newpc, rs1, imm, opcode") { +DEFINE_FUNC(riscv_core_gen_write, "nwReset, state, pc, instr, regrddata, regrddata2, imm") { if (vget(nwReset) == 0) { - vput(wRead, 0); - vput(bReadAddr, 0); - } else { - vput(wRead, 1); - VAssign(bReadAddr, newpc); - if (vget(state) == RISCVSTATE_EXEC_INST) { - unsigned int opcode = vget(opcode); - if (opcode == 0x00) { /* LOAD */ - vput(wRead, 1); - vput(bReadAddr, vget(rs1) + vget(imm)); - } else if (opcode == 0x08) {/* STORE */ - vput(wRead, 0); - vput(bReadAddr, 0); - } - } + vput(write, 0); } -} END_DEFINE_FUNC - -DEFINE_FUNC(riscv_core_gen_write, "nwReset, state, opcode, rs1, imm, rs2, func3") { - vput(write, 0); - vput(writeaddr, 0); - vput(writemask, 0); - vput(writedata, 0); - if (vget(nwReset) && vget(state) == RISCVSTATE_EXEC_INST && vget(opcode)==0x08) { - unsigned int newwriteaddr = vget(rs1) + vget(imm); - unsigned int rs2 = vget(rs2); - vput(write, 1); - vput(writeaddr, newwriteaddr); - vput(writemask, 0); - vput(writedata, rs2); - switch (vget(func3)) { + else if (vget(state) == RISCVSTATE_EXEC_INST) { + unsigned int pc = vget(pc); + unsigned int instr = vget(instr); + unsigned int rs1 = vget(regrddata); + unsigned int rs2 = vget(regrddata2); + unsigned int opcode = instr & 0x7f; + opcode >>= 2; + if (opcode == 0x08) { + unsigned int imm; + unsigned int func3; + unsigned int v; + unsigned int writeaddr; + unsigned int writemask; + unsigned int writedata; + func3 = (instr >> 12) & 0x7; + imm = vget(imm); + v = 0; + /* riscv支持地址不对齐访问,但是假定写在一个32位字中 */ + writeaddr = rs1 + imm; + writemask = 0; + writedata = rs2; + switch (func3) { case 0:/*sb*/ - switch (newwriteaddr & 3) { - case 0: vput(writemask, 0xe); vput(writedata, rs2); break; //1110 - case 1: vput(writemask, 0xd); vput(writedata, rs2 << 8); break; //1101 - case 2: vput(writemask, 0xb); vput(writedata, rs2 << 16); break; //1011 - case 3: vput(writemask, 0x7); vput(writedata, rs2 << 24); break; //0111 + switch (writeaddr & 3) { + case 0: writemask = 0xe; writedata <<= 0; break; //1110 + case 1: writemask = 0xd; writedata <<= 8; break; //1101 + case 2: writemask = 0xb; writedata <<= 16; break; //1011 + case 3: writemask = 0x7; writedata <<= 24; break; //0111 } break; case 1:/*sh*/ - switch (newwriteaddr & 3) { - case 0: vput(writemask, 0xc); vput(writedata, rs2); break; //1100 - case 1: vput(writemask, 0x9); vput(writedata, rs2 << 8); break; //1001 - case 2: vput(writemask, 0x3); vput(writedata, rs2 << 16); break; //0011 - case 3: { - printf("we support store instruction write in one word only %08x: %08x\n", vget(pc), vget(instr)); - exit(-6); - }break; + switch (writeaddr & 3) { + case 0: writemask = 0xc; writedata <<= 0; break; //1100 + case 1: writemask = 0x9; writedata <<= 8; break; //1001 + case 2: writemask = 0x3; writedata <<= 16; break; //0011 + case 3: writemask = 0x7; writedata <<= 24; break; //0111 /*ST2*/ } break; case 2:/*sw*/ - if (newwriteaddr & 3) { - printf("we support store instruction write in one word only %08x: %08x\n", vget(pc), vget(instr)); - exit(-6); + switch (writeaddr & 3) { + case 0: writemask = 0x0; writedata <<= 0; break; // 0000 + case 1: writemask = 0x1; writedata <<= 8; break; // 0001 /*ST2*/ + case 2: writemask = 0x3; writedata <<= 16; break; //0011 /*ST2*/ + case 3: writemask = 0x7; writedata <<= 24; break; //0111 /*ST2*/ } break; default: DEBUG_CODE_FUNC; exit(-7); break; + } + vput(writeaddr, writeaddr); + vput(write, 1); + vput(writedata, writedata); + vput(writemask, writemask); + } + else { + vput(write, 0); + } + } + else if (vget(state) == RISCVSTATE_WAIT_ST) { + unsigned int instr = vget(instr); + unsigned int lastaddr = vget(lastaddr); + unsigned int lastv = vget(lastv); + unsigned int func3; + unsigned int writemask = 0; + unsigned int writedata = 0; + func3 = (instr >> 12) & 0x7; + vput(write, 0); + switch (func3) { + case 1:/*sh*/ + switch (lastaddr & 3) { + case 3: writemask = 0xe; writedata = lastv >> 24; vput(write, 1); break; //1110 /*ST2*/ + } + break; + case 2:/*sw*/ + switch (lastaddr & 3) { + case 1: writemask = 0xe; writedata = lastv >> 24; vput(write, 1); break; // 1110 /*ST2*/ + case 2: writemask = 0xc; writedata = lastv >> 16; vput(write, 1); break; //1100 /*ST2*/ + case 3: writemask = 0x8; writedata = lastv >> 8; vput(write, 1); break; //1000 /*ST2*/ + } + break; } + vput(writeaddr, lastaddr + 4); + vput(writedata, writedata); + vput(writemask, writemask); + } + else { + vput(write, 0); } } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_ldaddr, "state, rs1, imm") { - if (vget(state) == RISCVSTATE_EXEC_INST) { - vput(ldaddr, vget(rs1) + vget(imm)); +DEFINE_FUNC(riscv_core_reg_gen_readreg, "state, instr") { + int state = vget(state); + if (state == RISCVSTATE_EXEC_INST) { + unsigned int instr = vget(instr); + unsigned int opcode = instr & 0x7f; + opcode >>= 2; + if (opcode == 0x00) { + unsigned int rd; + rd = (instr >> 7) & 0x1f; + vput(readreg, rd); + } } } END_DEFINE_FUNC -DEFINE_FUNC(riscv_core_gen_dstreg, "state, ldaddr, func3_r, rd_r, bReadData, pc, rs1, rs2, divclk, instr, imm") { - unsigned int state = vget(state); - vput(dstvalue, 0); - vput(dstreg, 0); - switch (state) { - case RISCVSTATE_WAIT_LD: { - unsigned int ldaddr = vget(ldaddr); - unsigned int data = vget(bReadData); - VAssign(dstreg, rd_r); - switch (vget(func3_r)) { - case 0: { - switch (ldaddr & 3) { - case 0: { - data = sign_expand(data, 7); - vput(dstvalue, data); - }break; - case 1: { - data >>= 8; - data = sign_expand(data, 7); - vput(dstvalue, data); - }break; - case 2: { - data >>= 16; - data = sign_expand(data, 7); - vput(dstvalue, data); - }break; - case 3: { - data >>= 24; - data = sign_expand(data, 7); - vput(dstvalue, data); - }break; - } - } break; - case 1: { - switch (ldaddr & 3) { - case 0: { - data = sign_expand(data, 15); - vput(dstvalue, data); - }break; - case 1: { - data >>= 8; - data = sign_expand(data, 15); - vput(dstvalue, data); - }break; - case 2: { - data >>= 16; - data = sign_expand(data, 15); - vput(dstvalue, data); - }break; - case 3: { - vput(dstvalue, 0xdeadbeef); - }break; - } - } break; - case 2: { - vput(dstvalue, data); - } break; - case 4: { - switch (ldaddr & 3) { - case 0: { - vput(dstvalue, data & 0xff); - }break; - case 1: { - data >>= 8; - vput(dstvalue, data & 0xff); - }break; - case 2: { - data >>= 16; - vput(dstvalue, data & 0xff); - }break; - case 3: { - data >>= 24; - vput(dstvalue, data & 0xff); - }break; - } - } break; - case 5: { - switch (ldaddr & 3) { - case 0: { - vput(dstvalue, data & 0xffff); - }break; - case 1: { - data >>= 8; - vput(dstvalue, data & 0xffff); - }break; - case 2: { - data >>= 16; - vput(dstvalue, data & 0xffff); - }break; - case 3: { - data >>= 24; - vput(dstvalue, data & 0xffff); - }break; - } - }break; +DEFINE_FUNC(riscv_core_reg_gen_instr, "state, bReadData") { + int state = vget(state); + if (state == RISCVSTATE_READ_REGS) { + vput(instr, vget(bReadData)); + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_reg_gen_divclk, "state, instr, divclk") { + int state = vget(state); + if (state == RISCVSTATE_EXEC_INST) { + unsigned int instr = vget(instr); + unsigned int opcode = instr & 0x7f; + unsigned int func3 = (instr >> 12) & 0x7; + opcode >>= 2; + if (opcode == 0x0c && (instr & (1 << 25)) && (func3 & 4)) { + vput(divclk, 11); } - }break; - /* RISCVSTATE_WAIT_DIV: if (divclk == 0) begin - case (func3_r[1:0]) - 0: begin //div - dstreg = rd_r; - dstvalue = divs_result; - end - 1: begin //divu - dstreg = rd_r; - dstvalue = div_result; - end - 2: begin//rem - dstreg = rd_r; - dstvalue = mods_result; - end - 3: begin //remu - dstreg = rd_r; - dstvalue = mod_result; - end - endcase - end - */ - case RISCVSTATE_EXEC_INST: { - VAssign(dstreg, rd); - switch (vget(opcode)) { - case 0x0d: { - VAssign(dstvalue, imm); - } break; - case 0x05: { - vput(dstvalue, vget(imm) + vget(pc)); - } break; - case 0x1b: { - vput(dstvalue, vget(pc) + 4); - } break; - case 0x19: { - vput(dstvalue, vget(pc) + 4); + } + else if (state == RISCVSTATE_WAIT_DIV) { + if (vget(divclk) != 0) { + vput(divclk, vget(divclk) - 1); } - case 0x04: { /* alui */ - unsigned int rs1 = vget(rs1); - unsigned int imm = vget(imm); - switch (vget(func3)) { - case 0:/*addi*/ vput(dstvalue, rs1 + imm); break; - case 1:/*slli*/ vput(dstvalue, rs1 << (imm & 0x1f)); break; - case 2:/*slti*/ vput(dstvalue, *(int*)&rs1 < *(int*)&imm ? 1 : 0); break; - case 3:/*sltiu*/vput(dstvalue, rs1 < imm ? 1 : 0); break; - case 4:/*xori*/ vput(dstvalue, rs1 ^ imm); break; - case 5:/*srli/srai*/ - vput(dstvalue, (vget(instr) & (1 << 30)) ? ((*(int*)&rs1) >> (imm & 0x1f)) : (rs1 >> (imm & 0x1f))); break; - case 6:/*ori*/ vput(dstvalue, rs1 | imm); break; - case 7:/*andi*/ vput(dstvalue, rs1 & imm); break; - default: vput(dstreg, 0); break; - } - } break; - case 0x0c: { - unsigned int rd = vget(rd); - unsigned int func3 = vget(func3); - unsigned int instr = vget(instr); - unsigned int rs1 = vget(rs1); - unsigned int rs2 = vget(rs2); - unsigned int rst; + } +} END_DEFINE_FUNC + - rst = 0; - if (instr & (1 << 25)) {/* is M instr*/ +DEFINE_FUNC(riscv_core_reg_gen_pc, "nwReset, state, instr, pc, imm, regrddata, regrddata2") { + if (vget(nwReset) == 0) { + vput(pc, 0x74); + } + else { + int state = vget(state); + if (state == RISCVSTATE_EXEC_INST) { + unsigned int instr = vget(instr); + unsigned int pc = vget(pc); + unsigned int rs1 = vget(regrddata); + unsigned int imm = vget(imm); + unsigned int opcode = instr & 0x7f; + opcode >>= 2; + + switch (opcode) { + case 0x1b: vput(pc, pc + imm); break; + case 0x19: vput(pc, rs1 + imm); break; + case 0x18: { + unsigned int func3; + unsigned int rs2 = vget(regrddata2); + int cond; + func3 = (instr >> 12) & 0x7; + cond = 0; switch (func3) { - case 0: { //mul - long long s1, s2; - s1 = *(int*)&rs1; - s2 = *(int*)&rs2; - s1 *= s2; - rst = *(unsigned int*)&s1; - }break; - case 1: { //mulh - long long s1, s2; - s1 = *(int*)&rs1; - s2 = *(int*)&rs2; - s1 *= s2; - rst = (*(unsigned long long*) & s1) >> 32; - }break; - case 2: { //mulhsu - long long s1, s2; - s1 = *(int*)&rs1; - s2 = rs2; - s1 *= s2; - rst = (*(unsigned long long*) & s1) >> 32; - }break; - case 3: { //mulhu - unsigned long long s1, s2; - s1 = rs1; - s2 = rs2; - s1 *= s2; - rst = s1 >> 32; - }break; -#if 1 - case 4: { //div - if (rs2 == 0) - rst = 0xffffffff; - else - *(int*)&rst = *(int*)&rs1 / *(int*)&rs2; - }break; - case 5: { //divu - if (rs2 == 0) - rst = 0xffffffff; - else - rst = rs1 / rs2; - }break; - case 6: { //rem - if (rs2 == 0) - rst = rs1; - else - *(int*)&rst = *(int*)&rs1 % *(int*)&rs2; - }break; - case 7: { //remu - if (rs2 == 0) - rst = rs1; - else - rst = rs1 % rs2; - }break; -#endif + case 0:/*beq*/ cond = rs1 == rs2; break; + case 1:/*bne*/ cond = rs1 != rs2; break; + case 4:/*blt*/ cond = (*(int*)&rs1) < (*(int*)&rs2); break; + case 5:/*bge*/ cond = (*(int*)&rs1) >= (*(int*)&rs2); break; + case 6:/*bltu*/cond = rs1 < rs2; break; + case 7:/*bgeu*/cond = rs1 >= rs2; break; + default: + INSTR_FORMAT_ERROR; + exit(-2); + break; } + if (cond) + vput(pc, pc + imm); + else + vput(pc, pc + 4); + }break; + default: { + vput(pc, pc + 4); + break; } - else { - switch (func3) { - case 0: { //add/sub - if (instr & (1 << 30)) - rst = rs1 - rs2; - else - rst = rs1 + rs2; - }break; - case 1: { //sll - rst = rs1 << rs2; - }break; - case 2: { //slt - rst = (*(int*)&rs1 < *(int*)&rs2) ? 1 : 0; - }break; - case 3: { //sltu - rst = (rs1 < rs2) ? 1 : 0; - }break; - case 4: { //xor - rst = rs1 ^ rs2; - }break; - case 5: { //srl/sra - if (instr & (1 << 30)) - rst = rs1 >> rs2; - else - *(int*)&rst = (*(int*)&rs1) >> rs2; - }break; - case 6: { //or - rst = rs1 | rs2; - }break; - case 7: { //and - rst = rs1 & rs2; - }break; - - } } - vput(dstreg, rd); - vput(dstvalue, rst); - } break; } - } break; } - } END_DEFINE_FUNC - - MODULE_INIT(riscv_core) - PORT_IN(wClk, 1); - PORT_IN(nwReset, 1); - GPORT_OUT(wWrite, 1, riscv_core_wr_sig); - GPORT_OUT(bWriteAddr, 32, riscv_core_wr_sig); - GPORT_OUT(bWriteData, 32, riscv_core_wr_sig); - GPORT_OUT(bWriteMask, 4, riscv_core_wr_sig); - GPORT_OUT(wRead, 1, riscv_core_read_sig); - GPORT_OUT(bReadAddr, 32, riscv_core_read_sig); - PORT_IN(bReadData, 32); - GREG(cur_instr, 32, riscv_core_gen_cur_instr); - GWIRE(instr, 32, riscv_core_reg_gen_instr); - GWIRE(rs1_no, 5, riscv_core_gen_rs1_no); - GWIRE(rs2_no, 5, riscv_core_gen_rs2_no); - GWIRE(opcode, 5, riscv_core_gen_opcode); - GWIRE(rd, 5, riscv_core_gen_rd); - GWIRE(func3, 3, riscv_core_gen_func3); - GWIRE(rd_r, 5, riscv_core_gen_rd_r); - GWIRE(func3_r, 3, riscv_core_gen_func3_r); - GWIRE(cond, 1, riscv_core_gen_cond); - GWIRE(rs1, 32, riscv_core_gen_rs1); - GWIRE(rs2, 32, riscv_core_gen_rs2); - GWIRE(imm, 32, riscv_core_gen_imm); - GREG(state, 4, riscv_core_gen_state); - GWIRE(newpc, 32, riscv_core_gen_newpc); - GREG(pc, 32, riscv_core_reg_gen_pc); - - GWIRE(write, 1, riscv_core_gen_write); - GWIRE(writeaddr, 32, riscv_core_gen_write); - GWIRE(writedata, 32, riscv_core_gen_write); - GWIRE(writemask, 4, riscv_core_gen_write); - GWIRE(dstreg, 5, riscv_core_gen_dstreg); - GWIRE(dstvalue, 32, riscv_core_gen_dstreg); - GREG(ldaddr, 32, riscv_core_gen_ldaddr); - GREG(x1, 32, riscv_core_register); - GREG(x2, 32, riscv_core_register); - GREG(x3, 32, riscv_core_register); - GREG(x4, 32, riscv_core_register); - GREG(x5, 32, riscv_core_register); - GREG(x6, 32, riscv_core_register); - GREG(x7, 32, riscv_core_register); - GREG(x8, 32, riscv_core_register); - GREG(x9, 32, riscv_core_register); - GREG(x10, 32, riscv_core_register); - GREG(x11, 32, riscv_core_register); - GREG(x12, 32, riscv_core_register); - GREG(x13, 32, riscv_core_register); - GREG(x14, 32, riscv_core_register); - GREG(x15, 32, riscv_core_register); - GREG(x16, 32, riscv_core_register); - GREG(x17, 32, riscv_core_register); - GREG(x18, 32, riscv_core_register); - GREG(x19, 32, riscv_core_register); - GREG(x20, 32, riscv_core_register); - GREG(x21, 32, riscv_core_register); - GREG(x22, 32, riscv_core_register); - GREG(x23, 32, riscv_core_register); - GREG(x24, 32, riscv_core_register); - GREG(x25, 32, riscv_core_register); - GREG(x26, 32, riscv_core_register); - GREG(x27, 32, riscv_core_register); - GREG(x28, 32, riscv_core_register); - GREG(x29, 32, riscv_core_register); - GREG(x30, 32, riscv_core_register); - GREG(x31, 32, riscv_core_register); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_reg_gen_lastv, "state, instr, ldaddr") { + unsigned int state = vget(state); + if (state == RISCVSTATE_WAIT_LD) { + unsigned int instr = vget(instr); + unsigned int func3 = (instr >> 12) & 0x7; + unsigned int v; + unsigned int ldaddr = vget(ldaddr); + vput(lastaddr, ldaddr); + ldaddr &= 3; + v = vget(bReadData); + if (func3 == 1 && ldaddr == 3) { /* lh */ + vput(lastv, v >> 24); + } + else if (func3 == 2 && ldaddr != 0) { /* lw */ + vput(lastv, v >> (ldaddr * 8)); + } + else if (func3 == 5 && ldaddr == 3) { /* lhu */ + vput(lastv, v >> 24); + } + } + else if (state == RISCVSTATE_EXEC_INST) { + unsigned int rs1 = vget(regrddata); + unsigned int rs2 = vget(regrddata2); + unsigned int imm = vget(imm); + vput(lastaddr, rs1 + imm); + vput(lastv, rs2); + } +}END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_clktick, "") { + if (vget(nwReset) == 0) { + + } + else { + int state = vget(state); + switch (state) { + case RISCVSTATE_EXEC_INST: { + CALL_FUNC(riscv_core_exec_inst); + }break; + } + } +} END_DEFINE_FUNC + +MODULE_INIT(riscv_core) +PORT_IN(wClk, 1); +PORT_IN(nwReset, 1); +GPORT_OUT(wWrite, 1, riscv_core_wr_sig); +GPORT_OUT(bWriteAddr, 32, riscv_core_wr_sig); +GPORT_OUT(bWriteData, 32, riscv_core_wr_sig); +GPORT_OUT(bWriteMask, 4, riscv_core_wr_sig); +GPORT_OUT(wRead, 1, riscv_core_read_sig); +GPORT_OUT(bReadAddr, 32, riscv_core_read_sig); +PORT_IN(bReadData, 32); +GPORT_OUT(regno, 5, riscv_core_reg_wr_sig); +GPORT_OUT(regena, 4, riscv_core_reg_wr_sig); +GPORT_OUT(regwrdata, 32, riscv_core_reg_wr_sig); +GPORT_OUT(regwren, 1, riscv_core_reg_wr_sig); +PORT_IN(regrddata, 32); +GPORT_OUT(regno2, 5, riscv_core_reg_wr_sig); +GPORT_OUT(regena2, 4, riscv_core_reg_wr_sig); +GPORT_OUT(regwrdata2, 32, riscv_core_reg_wr_sig); +GPORT_OUT(regwren2, 1, riscv_core_reg_wr_sig); +PORT_IN(regrddata2, 32); +GREG(pc, 32, riscv_core_reg_gen_pc); +GREG(instr, 32, riscv_core_reg_gen_instr); +GREG(write, 1, riscv_core_gen_write); +GREG(writeaddr, 32, riscv_core_gen_write); +GREG(writedata, 32, riscv_core_gen_write); +GREG(writemask, 4, riscv_core_gen_write); +GREG(readreg, 5, riscv_core_reg_gen_readreg); +GREG(state, 4, riscv_core_gen_state); +GREG(imm, 32, riscv_core_gen_imm); +GREG(dstreg, 5, riscv_core_gen_dstreg); +GREG(dstvalue, 32, riscv_core_gen_dstreg); +GREG(ldaddr, 32, riscv_core_gen_ldaddr); +GREG(divclk, 6, riscv_core_reg_gen_divclk); +GREG(lastv, 32, riscv_core_reg_gen_lastv); +GREG(lastaddr, 32, riscv_core_reg_gen_lastv); + +CLKTICK_FUNC(riscv_core_clktick); END_MODULE_INIT(riscv_core) diff --git a/examples/hdl4se_riscv/hdl4se_riscv_sim/hdl4se_riscv_core_v4_1.c b/examples/hdl4se_riscv/hdl4se_riscv_sim/hdl4se_riscv_core_v4_1.c new file mode 100644 index 0000000000000000000000000000000000000000..2ccc3ca9dc179bd2467372170b74a585f46aa468 --- /dev/null +++ b/examples/hdl4se_riscv/hdl4se_riscv_sim/hdl4se_riscv_core_v4_1.c @@ -0,0 +1,863 @@ +/* +** HDL4SE: 软件Verilog综合仿真平台 +** Copyright (C) 2021-2021, raoxianhong +** LCOM: 轻量级组件对象模型 +** Copyright (C) 2021-2021, raoxianhong +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +* hdl4se_riscv_core_v2.c + 202108261008: rxh, initial version +*/ + +#include "stdlib.h" +#include "stdio.h" +#include "object.h" +#include "dlist.h" +#include "string.h" +#include "stdarg.h" +#include "bignumber.h" +#include "hdl4secell.h" + +#define IMPLEMENT_GUID +#include "hdl4se_riscv.h" +#undef IMPLEMENT_GUID + +#define riscv_core_MODULE_VERSION_STRING "0.4.2-20210826.1008 RISCV Core cell" +#define riscv_core_MODULE_CLSID CLSID_HDL4SE_RISCV_CORE + +#define M_ID(id) riscv_core##id + +IDLIST + VID(wClk), + VID(nwReset), + VID(wWrite), + VID(bWriteAddr), + VID(bWriteData), + VID(bWriteMask), + VID(wRead), + VID(bReadAddr), + VID(bReadData), + VID(pc), + VID(instr), + VID(write), + VID(writeaddr), + VID(writedata), + VID(writemask), + VID(readreg), + VID(state), + VID(imm), + VID(dstreg), + VID(dstvalue), + VID(ldaddr), + VID(divclk), + VID(rs1), + VID(rs2), + VID(cur_instr), + VID(rs1_no), + VID(rs2_no), + VID(opcode), + VID(rd), + VID(func3), + VID(rd_r), + VID(func3_r), + VID(cond), + VID(newpc), + VID(x1), + VID(x2), + VID(x3), + VID(x4), + VID(x5), + VID(x6), + VID(x7), + VID(x8), + VID(x9), + VID(x10), + VID(x11), + VID(x12), + VID(x13), + VID(x14), + VID(x15), + VID(x16), + VID(x17), + VID(x18), + VID(x19), + VID(x20), + VID(x21), + VID(x22), + VID(x23), + VID(x24), + VID(x25), + VID(x26), + VID(x27), + VID(x28), + VID(x29), + VID(x30), + VID(x31), +END_IDLIST + +enum riscv_core_state { + RISCVSTATE_STARTUP, + RISCVSTATE_EXEC_INST, + RISCVSTATE_WAIT_LD, + RISCVSTATE_WAIT_ST, + RISCVSTATE_WAIT_DIV, +}; + +MODULE_DECLARE(riscv_core) +END_MODULE_DECLARE(riscv_core) + +FILE* recordfileGet(); + +#define DEBUG_CODE_FUNC fprintf(recordfileGet(), "%30s: %08x: %08x\n", __FUNCTION__, vget(pc), vget(instr)) +#define DEBUG_CODE_DECODE fprintf(recordfileGet(), +#define INSTR_FORMAT_ERROR fprintf(recordfileGet(), "instruction format error, we support rv32im only: pc=%08x: %x\n", vget(pc), vget(instr)); + + +static unsigned int sign_expand(unsigned int v, int bit) +{ + int i; + if (v & (1 << bit)) { + for (i = bit + 1; i < 32; i++) { + v |= 1 << i; + } + } + return v; +} + +DEFINE_FUNC(riscv_core_wr_sig, "write, writeaddr, writedata, writemask") { + VAssign(wWrite, write); + VAssign(bWriteAddr, writeaddr); + VAssign(bWriteData, writedata); + VAssign(bWriteMask, writemask); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_cur_instr, "bReadData") { + VAssign(cur_instr, bReadData); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_reg_gen_instr, "bReadData") { + VAssign(instr, bReadData); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_rs1_no, "instr") { + vput(rs1_no, (vget(instr) >> 15) & 0x1f); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_rs2_no, "instr") { + vput(rs2_no, (vget(instr) >> 20) & 0x1f); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_opcode, "instr") { + vput(opcode, (vget(instr) >> 2) & 0x1f); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_rd, "instr") { + vput(rd, (vget(instr) >> 7) & 0x1f); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_func3, "instr") { + vput(func3, (vget(instr) >> 12) & 0x7); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_rd_r, "cur_instr") { + vput(rd_r, (vget(cur_instr) >> 7) & 0x1f); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_func3_r, "cur_instr") { + vput(func3_r, (vget(cur_instr) >> 12) & 0x7); +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_rs1, + "rs1_no, " + "x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, " + "x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, " + "x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31" +) { + switch (vget(rs1_no)) { + case 0: vput(rs1, 0); break; + case 1: VAssign(rs1, x1); break; + case 2: VAssign(rs1, x2); break; + case 3: VAssign(rs1, x3); break; + case 4: VAssign(rs1, x4); break; + case 5: VAssign(rs1, x5); break; + case 6: VAssign(rs1, x6); break; + case 7: VAssign(rs1, x7); break; + case 8: VAssign(rs1, x8); break; + case 9: VAssign(rs1, x9); break; + case 10: VAssign(rs1, x10); break; + case 11: VAssign(rs1, x11); break; + case 12: VAssign(rs1, x12); break; + case 13: VAssign(rs1, x13); break; + case 14: VAssign(rs1, x14); break; + case 15: VAssign(rs1, x15); break; + case 16: VAssign(rs1, x16); break; + case 17: VAssign(rs1, x17); break; + case 18: VAssign(rs1, x18); break; + case 19: VAssign(rs1, x19); break; + case 20: VAssign(rs1, x20); break; + case 21: VAssign(rs1, x21); break; + case 22: VAssign(rs1, x22); break; + case 23: VAssign(rs1, x23); break; + case 24: VAssign(rs1, x24); break; + case 25: VAssign(rs1, x25); break; + case 26: VAssign(rs1, x26); break; + case 27: VAssign(rs1, x27); break; + case 28: VAssign(rs1, x28); break; + case 29: VAssign(rs1, x29); break; + case 30: VAssign(rs1, x30); break; + case 31: VAssign(rs1, x31); break; + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_rs2, + "rs2_no, " + "x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, " + "x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, " + "x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31" +) { + switch (vget(rs2_no)) { + case 0: vput(rs2, 0); break; + case 1: VAssign(rs2, x1); break; + case 2: VAssign(rs2, x2); break; + case 3: VAssign(rs2, x3); break; + case 4: VAssign(rs2, x4); break; + case 5: VAssign(rs2, x5); break; + case 6: VAssign(rs2, x6); break; + case 7: VAssign(rs2, x7); break; + case 8: VAssign(rs2, x8); break; + case 9: VAssign(rs2, x9); break; + case 10: VAssign(rs2, x10); break; + case 11: VAssign(rs2, x11); break; + case 12: VAssign(rs2, x12); break; + case 13: VAssign(rs2, x13); break; + case 14: VAssign(rs2, x14); break; + case 15: VAssign(rs2, x15); break; + case 16: VAssign(rs2, x16); break; + case 17: VAssign(rs2, x17); break; + case 18: VAssign(rs2, x18); break; + case 19: VAssign(rs2, x19); break; + case 20: VAssign(rs2, x20); break; + case 21: VAssign(rs2, x21); break; + case 22: VAssign(rs2, x22); break; + case 23: VAssign(rs2, x23); break; + case 24: VAssign(rs2, x24); break; + case 25: VAssign(rs2, x25); break; + case 26: VAssign(rs2, x26); break; + case 27: VAssign(rs2, x27); break; + case 28: VAssign(rs2, x28); break; + case 29: VAssign(rs2, x29); break; + case 30: VAssign(rs2, x30); break; + case 31: VAssign(rs2, x31); break; + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_register, "dstreg, dstvalue, nwReset") { + if (vget(nwReset) == 0) { + vput(x1, 0x8c); + vput(x2, RAMSIZE * 4 - 16); + } + else { + switch (vget(dstreg)) { + case 0: ; break; + case 1: VAssign(x1, dstvalue); break; + case 2: VAssign(x2, dstvalue); break; + case 3: VAssign(x3, dstvalue); break; + case 4: VAssign(x4, dstvalue); break; + case 5: VAssign(x5, dstvalue); break; + case 6: VAssign(x6, dstvalue); break; + case 7: VAssign(x7, dstvalue); break; + case 8: VAssign(x8, dstvalue); break; + case 9: VAssign(x9, dstvalue); break; + case 10: VAssign(x10, dstvalue); break; + case 11: VAssign(x11, dstvalue); break; + case 12: VAssign(x12, dstvalue); break; + case 13: VAssign(x13, dstvalue); break; + case 14: VAssign(x14, dstvalue); break; + case 15: VAssign(x15, dstvalue); break; + case 16: VAssign(x16, dstvalue); break; + case 17: VAssign(x17, dstvalue); break; + case 18: VAssign(x18, dstvalue); break; + case 19: VAssign(x19, dstvalue); break; + case 20: VAssign(x20, dstvalue); break; + case 21: VAssign(x21, dstvalue); break; + case 22: VAssign(x22, dstvalue); break; + case 23: VAssign(x23, dstvalue); break; + case 24: VAssign(x24, dstvalue); break; + case 25: VAssign(x25, dstvalue); break; + case 26: VAssign(x26, dstvalue); break; + case 27: VAssign(x27, dstvalue); break; + case 28: VAssign(x28, dstvalue); break; + case 29: VAssign(x29, dstvalue); break; + case 30: VAssign(x30, dstvalue); break; + case 31: VAssign(x31, dstvalue); break; + } + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_cond, "func3, rs1, rs2") { + unsigned int rs1, rs2; + rs1 = vget(rs1); + rs2 = vget(rs2); + switch (vget(func3)) { + case 0:/*beq*/ vput(cond, rs1 == rs2 ? 1 : 0); break; + case 1:/*bne*/ vput(cond, rs1 != rs2 ? 1 : 0); break; + case 4:/*blt*/ vput(cond, (*(int*)&rs1) < (*(int*)&rs2) ? 1 : 0); break; + case 5:/*bge*/ vput(cond, (*(int*)&rs1) >= (*(int*)&rs2) ? 1 : 0); break; + case 6:/*bltu*/vput(cond, rs1 < rs2 ? 1 : 0); break; + case 7:/*bgeu*/vput(cond, rs1 >= rs2 ? 1 : 0); break; + default: + vput(cond, 0); + INSTR_FORMAT_ERROR; + exit(-2); + break; + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_imm, "instr") { + unsigned int instr; + unsigned int opcode; + instr = vget(instr); + opcode = instr & 0x7f; + opcode >>= 2; + switch (opcode) { + case 0x0d: { + vput(imm, instr & 0xfffff000); + }break; + case 0x05: { + vput(imm, instr & 0xfffff000); + }break; + case 0x1b: { + unsigned int imm; + imm = (instr & (1 << 20)) ? (1 << 11) : 0; + imm |= (instr >> 20) & 0x7fe; + imm |= instr & 0xff000; + imm |= instr & (1 << 31) ? 0x100000 : 0; + imm = sign_expand(imm, 20); + vput(imm, imm); + }break; + case 0x19: { + unsigned int imm; + imm = instr >> 20; + imm = sign_expand(imm, 11); + vput(imm, imm); + }break; + case 0x18: { + unsigned int imm; + unsigned int immh; + unsigned int immd; + + immh = instr >> 25; + immd = (instr >> 7) & 0x1f; + imm = immd & 0x1e; + imm |= (immh & 0x3f) << 5; + imm |= (immd & 1) << 11; + imm |= (immh & 0x40) ? (1 << 12) : 0; + imm = sign_expand(imm, 12); + vput(imm, imm); + }break; + case 0x00: { + unsigned int imm; + imm = instr >> 20; + imm = sign_expand(imm, 11); + vput(imm, imm); + }break; + case 0x08: { + unsigned int imm; + imm = ((instr >> 20) & 0xfe0) | ((instr >> 7) & 0x1f); + imm = sign_expand(imm, 11); + vput(imm, imm); + }break; + case 0x04: { + unsigned int imm; + imm = instr >> 20; + imm = sign_expand(imm, 11); + vput(imm, imm); + }break; + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_state, "state, instr, opcode, func3, rs2, nwReset") { + if (vget(nwReset) == 0) { + vput(state, RISCVSTATE_STARTUP); + } + else { + int state = vget(state); + switch (state) { + case RISCVSTATE_STARTUP: { + vput(state, RISCVSTATE_EXEC_INST); + }break; + case RISCVSTATE_EXEC_INST: { + unsigned int instr = vget(instr); + unsigned int opcode = vget(opcode); + unsigned int func3 = vget(func3); + unsigned int rs2 = vget(rs2); + if (opcode == 0x00) + vput(state, RISCVSTATE_WAIT_LD);//ld + else if (opcode == 0x08) + vput(state, RISCVSTATE_WAIT_ST);//st + /* else if (opcode == 0x0c && (instr & (1 << 25)) && (func3 & 4) && rs2 != 0) { + vput(state, RISCVSTATE_WAIT_DIV); + }*/ + }break; + case RISCVSTATE_WAIT_LD: { + vput(state, RISCVSTATE_EXEC_INST); + }break; + case RISCVSTATE_WAIT_ST: { + vput(state, RISCVSTATE_EXEC_INST); + }break; + /*case RISCVSTATE_WAIT_DIV: { + if (vget(divclk) == 0) + vput(state, RISCVSTATE_EXEC_INST); + }break;*/ + } + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_newpc, "state, opcode, pc, imm, rs1, cond") { + if (vget(state) == RISCVSTATE_EXEC_INST) { + switch (vget(opcode)) { + case 0x1b: vput(newpc, vget(pc) + vget(imm)); break; + case 0x19: vput(newpc, vget(rs1) + vget(imm)); break; + case 0x18: vput(newpc, vget(cond) ? (vget(pc) + vget(imm)) : (vget(pc) + 4)); break; + default : vput(newpc, vget(pc) + 4); break; + } + } + else { + VAssign(newpc, pc); + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_reg_gen_pc, "nwReset, newpc") { + if (vget(nwReset) == 0) { + vput(pc, 0x74); + } + else { + VAssign(pc, newpc); + } +} END_DEFINE_FUNC + + +DEFINE_FUNC(riscv_core_read_sig, "nwReset, state, newpc, rs1, imm, opcode") { + if (vget(nwReset) == 0) { + vput(wRead, 0); + vput(bReadAddr, 0); + } else { + vput(wRead, 1); + VAssign(bReadAddr, newpc); + if (vget(state) == RISCVSTATE_EXEC_INST) { + unsigned int opcode = vget(opcode); + if (opcode == 0x00) { /* LOAD */ + vput(wRead, 1); + vput(bReadAddr, vget(rs1) + vget(imm)); + } else if (opcode == 0x08) {/* STORE */ + vput(wRead, 0); + vput(bReadAddr, 0); + } + } + } +} END_DEFINE_FUNC + +DEFINE_FUNC(riscv_core_gen_write, "nwReset, state, opcode, rs1, imm, rs2, func3") { + vput(write, 0); + vput(writeaddr, 0); + vput(writemask, 0); + vput(writedata, 0); + if (vget(nwReset) && vget(state) == RISCVSTATE_EXEC_INST && vget(opcode)==0x08) { + unsigned int newwriteaddr = vget(rs1) + vget(imm); + unsigned int rs2 = vget(rs2); + vput(write, 1); + vput(writeaddr, newwriteaddr); + vput(writemask, 0); + vput(writedata, rs2); + switch (vget(func3)) { + case 0:/*sb*/ + switch (newwriteaddr & 3) { + case 0: vput(writemask, 0xe); vput(writedata, rs2); break; //1110 + case 1: vput(writemask, 0xd); vput(writedata, rs2 << 8); break; //1101 + case 2: vput(writemask, 0xb); vput(writedata, rs2 << 16); break; //1011 + case 3: vput(writemask, 0x7); vput(writedata, rs2 << 24); break; //0111 + } + break; + case 1:/*sh*/ + switch (newwriteaddr & 3) { + case 0: vput(writemask, 0xc); vput(writedata, rs2); break; //1100 + case 1: vput(writemask, 0x9); vput(writedata, rs2 << 8); break; //1001 + case 2: vput(writemask, 0x3); vput(writedata, rs2 << 16); break; //0011 + case 3: { + printf("we support store instruction write in one word only %08x: %08x\n", vget(pc), vget(instr)); + exit(-6); + }break; + } + break; + case 2:/*sw*/ + if (newwriteaddr & 3) { + printf("we support store instruction write in one word only %08x: %08x\n", vget(pc), vget(instr)); + exit(-6); + } + break; + default: + DEBUG_CODE_FUNC; + exit(-7); + break; + } + } +} END_DEFINE_FUNC + + +DEFINE_FUNC(riscv_core_gen_ldaddr, "state, rs1, imm") { + if (vget(state) == RISCVSTATE_EXEC_INST) { + vput(ldaddr, vget(rs1) + vget(imm)); + } +} END_DEFINE_FUNC + + +DEFINE_FUNC(riscv_core_gen_dstreg, "state, ldaddr, func3_r, rd_r, bReadData, pc, rs1, rs2, divclk, instr, imm") { + unsigned int state = vget(state); + vput(dstvalue, 0); + vput(dstreg, 0); + switch (state) { + case RISCVSTATE_WAIT_LD: { + unsigned int ldaddr = vget(ldaddr); + unsigned int data = vget(bReadData); + VAssign(dstreg, rd_r); + switch (vget(func3_r)) { + case 0: { + switch (ldaddr & 3) { + case 0: { + data = sign_expand(data, 7); + vput(dstvalue, data); + }break; + case 1: { + data >>= 8; + data = sign_expand(data, 7); + vput(dstvalue, data); + }break; + case 2: { + data >>= 16; + data = sign_expand(data, 7); + vput(dstvalue, data); + }break; + case 3: { + data >>= 24; + data = sign_expand(data, 7); + vput(dstvalue, data); + }break; + } + } break; + case 1: { + switch (ldaddr & 3) { + case 0: { + data = sign_expand(data, 15); + vput(dstvalue, data); + }break; + case 1: { + data >>= 8; + data = sign_expand(data, 15); + vput(dstvalue, data); + }break; + case 2: { + data >>= 16; + data = sign_expand(data, 15); + vput(dstvalue, data); + }break; + case 3: { + vput(dstvalue, 0xdeadbeef); + }break; + } + } break; + case 2: { + vput(dstvalue, data); + } break; + case 4: { + switch (ldaddr & 3) { + case 0: { + vput(dstvalue, data & 0xff); + }break; + case 1: { + data >>= 8; + vput(dstvalue, data & 0xff); + }break; + case 2: { + data >>= 16; + vput(dstvalue, data & 0xff); + }break; + case 3: { + data >>= 24; + vput(dstvalue, data & 0xff); + }break; + } + } break; + case 5: { + switch (ldaddr & 3) { + case 0: { + vput(dstvalue, data & 0xffff); + }break; + case 1: { + data >>= 8; + vput(dstvalue, data & 0xffff); + }break; + case 2: { + data >>= 16; + vput(dstvalue, data & 0xffff); + }break; + case 3: { + data >>= 24; + vput(dstvalue, data & 0xffff); + }break; + } + }break; + } + }break; + /* RISCVSTATE_WAIT_DIV: if (divclk == 0) begin + case (func3_r[1:0]) + 0: begin //div + dstreg = rd_r; + dstvalue = divs_result; + end + 1: begin //divu + dstreg = rd_r; + dstvalue = div_result; + end + 2: begin//rem + dstreg = rd_r; + dstvalue = mods_result; + end + 3: begin //remu + dstreg = rd_r; + dstvalue = mod_result; + end + endcase + end + */ + case RISCVSTATE_EXEC_INST: { + VAssign(dstreg, rd); + switch (vget(opcode)) { + case 0x0d: { + VAssign(dstvalue, imm); + } break; + case 0x05: { + vput(dstvalue, vget(imm) + vget(pc)); + } break; + case 0x1b: { + vput(dstvalue, vget(pc) + 4); + } break; + case 0x19: { + vput(dstvalue, vget(pc) + 4); + } + case 0x04: { /* alui */ + unsigned int rs1 = vget(rs1); + unsigned int imm = vget(imm); + switch (vget(func3)) { + case 0:/*addi*/ vput(dstvalue, rs1 + imm); break; + case 1:/*slli*/ vput(dstvalue, rs1 << (imm & 0x1f)); break; + case 2:/*slti*/ vput(dstvalue, *(int*)&rs1 < *(int*)&imm ? 1 : 0); break; + case 3:/*sltiu*/vput(dstvalue, rs1 < imm ? 1 : 0); break; + case 4:/*xori*/ vput(dstvalue, rs1 ^ imm); break; + case 5:/*srli/srai*/ + vput(dstvalue, (vget(instr) & (1 << 30)) ? ((*(int*)&rs1) >> (imm & 0x1f)) : (rs1 >> (imm & 0x1f))); break; + case 6:/*ori*/ vput(dstvalue, rs1 | imm); break; + case 7:/*andi*/ vput(dstvalue, rs1 & imm); break; + default: vput(dstreg, 0); break; + } + } break; + case 0x0c: { + unsigned int rd = vget(rd); + unsigned int func3 = vget(func3); + unsigned int instr = vget(instr); + unsigned int rs1 = vget(rs1); + unsigned int rs2 = vget(rs2); + unsigned int rst; + + rst = 0; + if (instr & (1 << 25)) {/* is M instr*/ + switch (func3) { + case 0: { //mul + long long s1, s2; + s1 = *(int*)&rs1; + s2 = *(int*)&rs2; + s1 *= s2; + rst = *(unsigned int*)&s1; + }break; + case 1: { //mulh + long long s1, s2; + s1 = *(int*)&rs1; + s2 = *(int*)&rs2; + s1 *= s2; + rst = (*(unsigned long long*) & s1) >> 32; + }break; + case 2: { //mulhsu + long long s1, s2; + s1 = *(int*)&rs1; + s2 = rs2; + s1 *= s2; + rst = (*(unsigned long long*) & s1) >> 32; + }break; + case 3: { //mulhu + unsigned long long s1, s2; + s1 = rs1; + s2 = rs2; + s1 *= s2; + rst = s1 >> 32; + }break; +#if 1 + case 4: { //div + if (rs2 == 0) + rst = 0xffffffff; + else + *(int*)&rst = *(int*)&rs1 / *(int*)&rs2; + }break; + case 5: { //divu + if (rs2 == 0) + rst = 0xffffffff; + else + rst = rs1 / rs2; + }break; + case 6: { //rem + if (rs2 == 0) + rst = rs1; + else + *(int*)&rst = *(int*)&rs1 % *(int*)&rs2; + }break; + case 7: { //remu + if (rs2 == 0) + rst = rs1; + else + rst = rs1 % rs2; + }break; +#endif + } + } + else { + switch (func3) { + case 0: { //add/sub + if (instr & (1 << 30)) + rst = rs1 - rs2; + else + rst = rs1 + rs2; + }break; + case 1: { //sll + rst = rs1 << rs2; + }break; + case 2: { //slt + rst = (*(int*)&rs1 < *(int*)&rs2) ? 1 : 0; + }break; + case 3: { //sltu + rst = (rs1 < rs2) ? 1 : 0; + }break; + case 4: { //xor + rst = rs1 ^ rs2; + }break; + case 5: { //srl/sra + if (instr & (1 << 30)) + rst = rs1 >> rs2; + else + *(int*)&rst = (*(int*)&rs1) >> rs2; + }break; + case 6: { //or + rst = rs1 | rs2; + }break; + case 7: { //and + rst = rs1 & rs2; + }break; + + } + } + vput(dstreg, rd); + vput(dstvalue, rst); + } break; + } + } break; + } + } END_DEFINE_FUNC + + MODULE_INIT(riscv_core) + PORT_IN(wClk, 1); + PORT_IN(nwReset, 1); + GPORT_OUT(wWrite, 1, riscv_core_wr_sig); + GPORT_OUT(bWriteAddr, 32, riscv_core_wr_sig); + GPORT_OUT(bWriteData, 32, riscv_core_wr_sig); + GPORT_OUT(bWriteMask, 4, riscv_core_wr_sig); + GPORT_OUT(wRead, 1, riscv_core_read_sig); + GPORT_OUT(bReadAddr, 32, riscv_core_read_sig); + PORT_IN(bReadData, 32); + GREG(cur_instr, 32, riscv_core_gen_cur_instr); + GWIRE(instr, 32, riscv_core_reg_gen_instr); + GWIRE(rs1_no, 5, riscv_core_gen_rs1_no); + GWIRE(rs2_no, 5, riscv_core_gen_rs2_no); + GWIRE(opcode, 5, riscv_core_gen_opcode); + GWIRE(rd, 5, riscv_core_gen_rd); + GWIRE(func3, 3, riscv_core_gen_func3); + GWIRE(rd_r, 5, riscv_core_gen_rd_r); + GWIRE(func3_r, 3, riscv_core_gen_func3_r); + GWIRE(cond, 1, riscv_core_gen_cond); + GWIRE(rs1, 32, riscv_core_gen_rs1); + GWIRE(rs2, 32, riscv_core_gen_rs2); + GWIRE(imm, 32, riscv_core_gen_imm); + GREG(state, 4, riscv_core_gen_state); + GWIRE(newpc, 32, riscv_core_gen_newpc); + GREG(pc, 32, riscv_core_reg_gen_pc); + + GWIRE(write, 1, riscv_core_gen_write); + GWIRE(writeaddr, 32, riscv_core_gen_write); + GWIRE(writedata, 32, riscv_core_gen_write); + GWIRE(writemask, 4, riscv_core_gen_write); + GWIRE(dstreg, 5, riscv_core_gen_dstreg); + GWIRE(dstvalue, 32, riscv_core_gen_dstreg); + GREG(ldaddr, 32, riscv_core_gen_ldaddr); + GREG(x1, 32, riscv_core_register); + GREG(x2, 32, riscv_core_register); + GREG(x3, 32, riscv_core_register); + GREG(x4, 32, riscv_core_register); + GREG(x5, 32, riscv_core_register); + GREG(x6, 32, riscv_core_register); + GREG(x7, 32, riscv_core_register); + GREG(x8, 32, riscv_core_register); + GREG(x9, 32, riscv_core_register); + GREG(x10, 32, riscv_core_register); + GREG(x11, 32, riscv_core_register); + GREG(x12, 32, riscv_core_register); + GREG(x13, 32, riscv_core_register); + GREG(x14, 32, riscv_core_register); + GREG(x15, 32, riscv_core_register); + GREG(x16, 32, riscv_core_register); + GREG(x17, 32, riscv_core_register); + GREG(x18, 32, riscv_core_register); + GREG(x19, 32, riscv_core_register); + GREG(x20, 32, riscv_core_register); + GREG(x21, 32, riscv_core_register); + GREG(x22, 32, riscv_core_register); + GREG(x23, 32, riscv_core_register); + GREG(x24, 32, riscv_core_register); + GREG(x25, 32, riscv_core_register); + GREG(x26, 32, riscv_core_register); + GREG(x27, 32, riscv_core_register); + GREG(x28, 32, riscv_core_register); + GREG(x29, 32, riscv_core_register); + GREG(x30, 32, riscv_core_register); + GREG(x31, 32, riscv_core_register); +END_MODULE_INIT(riscv_core) diff --git a/examples/hdl4se_riscv/hdl4se_riscv_sim/main_v4.c b/examples/hdl4se_riscv/hdl4se_riscv_sim/main_v4.c index 32d4a6b1255164f6a569becadf2ba641541d2b11..4306f8d01729b41600e70b86b9bb1af3c9e07afe 100644 --- a/examples/hdl4se_riscv/hdl4se_riscv_sim/main_v4.c +++ b/examples/hdl4se_riscv/hdl4se_riscv_sim/main_v4.c @@ -60,6 +60,7 @@ IHDL4SEModuleVar* hdl4seCreate_main(IHDL4SEModuleVar* parent, const char* instan extern int (*A_u_t_o_registor_digitled)(); extern int (*A_u_t_o_registor_riscv_core)(); extern int (*A_u_t_o_registor_riscv_ram)(); +extern int (*A_u_t_o_registor_riscv_regfile)(); FILE* recordfile; THREADLOCK recordfilelock; @@ -85,6 +86,7 @@ int main(int argc, char* argv[]) A_u_t_o_registor_digitled(); A_u_t_o_registor_riscv_core(); A_u_t_o_registor_riscv_ram(); + A_u_t_o_registor_riscv_regfile(); recordfile = fopen("d:/gitwork/recordfile.txt", "w"); recordfilelock = threadlockCreate(); sim = hdl4sesimCreateSimulator(); @@ -92,7 +94,7 @@ int main(int argc, char* argv[]) objectCall1(sim, SetTopModule, topmodule); objectCall1(sim, SetReset, 0); #if RECORDVCD - vcdfile = hdl4sesimCreateVCDFile("riscv_v4.vcd"); + vcdfile = hdl4sesimCreateVCDFile("riscv_v2.vcd"); objectCall2(vcdfile, AddSignal, "/top/core", "pc"); objectCall2(vcdfile, AddSignal, "/top/core", "instr"); objectCall2(vcdfile, AddSignal, "/top/core", "state"); @@ -102,37 +104,42 @@ int main(int argc, char* argv[]) objectCall2(vcdfile, AddSignal, "/top/core", "wWrite"); objectCall2(vcdfile, AddSignal, "/top/core", "bWriteAddr"); objectCall2(vcdfile, AddSignal, "/top/core", "bWriteData"); - objectCall2(vcdfile, AddSignal, "/top/core", "x1"); - objectCall2(vcdfile, AddSignal, "/top/core", "x2"); - objectCall2(vcdfile, AddSignal, "/top/core", "x3"); - objectCall2(vcdfile, AddSignal, "/top/core", "x4"); - objectCall2(vcdfile, AddSignal, "/top/core", "x5"); - objectCall2(vcdfile, AddSignal, "/top/core", "x6"); - objectCall2(vcdfile, AddSignal, "/top/core", "x7"); - objectCall2(vcdfile, AddSignal, "/top/core", "x8"); - objectCall2(vcdfile, AddSignal, "/top/core", "x9"); - objectCall2(vcdfile, AddSignal, "/top/core", "x10"); - objectCall2(vcdfile, AddSignal, "/top/core", "x11"); - objectCall2(vcdfile, AddSignal, "/top/core", "x12"); - objectCall2(vcdfile, AddSignal, "/top/core", "x13"); - objectCall2(vcdfile, AddSignal, "/top/core", "x14"); - objectCall2(vcdfile, AddSignal, "/top/core", "x15"); - objectCall2(vcdfile, AddSignal, "/top/core", "x16"); - objectCall2(vcdfile, AddSignal, "/top/core", "x17"); - objectCall2(vcdfile, AddSignal, "/top/core", "x18"); - objectCall2(vcdfile, AddSignal, "/top/core", "x19"); - objectCall2(vcdfile, AddSignal, "/top/core", "x20"); - objectCall2(vcdfile, AddSignal, "/top/core", "x21"); - objectCall2(vcdfile, AddSignal, "/top/core", "x22"); - objectCall2(vcdfile, AddSignal, "/top/core", "x23"); - objectCall2(vcdfile, AddSignal, "/top/core", "x24"); - objectCall2(vcdfile, AddSignal, "/top/core", "x25"); - objectCall2(vcdfile, AddSignal, "/top/core", "x26"); - objectCall2(vcdfile, AddSignal, "/top/core", "x27"); - objectCall2(vcdfile, AddSignal, "/top/core", "x28"); - objectCall2(vcdfile, AddSignal, "/top/core", "x29"); - objectCall2(vcdfile, AddSignal, "/top/core", "x30"); - objectCall2(vcdfile, AddSignal, "/top/core", "x31"); + objectCall2(vcdfile, AddSignal, "/top/core", "regno"); + objectCall2(vcdfile, AddSignal, "/top/core", "regena"); + objectCall2(vcdfile, AddSignal, "/top/core", "regwrdata"); + objectCall2(vcdfile, AddSignal, "/top/core", "regwren"); + objectCall2(vcdfile, AddSignal, "/top/core", "regrddata"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x1"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x2"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x3"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x4"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x5"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x6"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x7"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x8"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x9"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x10"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x11"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x12"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x13"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x14"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x15"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x16"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x17"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x18"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x19"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x20"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x21"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x22"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x23"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x24"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x25"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x26"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x27"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x28"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x29"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x30"); + objectCall2(vcdfile, AddSignal, "/top/regs", "x31"); objectCall1(vcdfile, SetTopModule, topmodule); objectCall0(vcdfile, StartRecord); #endif diff --git a/examples/hdl4se_riscv/hdl4se_riscv_sim/riscv_sim_main_v4.c b/examples/hdl4se_riscv/hdl4se_riscv_sim/riscv_sim_main_v4.c index d1a2bc89d758574267ac34a72b0286a445459f74..87c5aec6b192b0476f34e1cd821f799e9f69dc7a 100644 --- a/examples/hdl4se_riscv/hdl4se_riscv_sim/riscv_sim_main_v4.c +++ b/examples/hdl4se_riscv/hdl4se_riscv_sim/riscv_sim_main_v4.c @@ -31,7 +31,7 @@ /* -* Created by HDL4SE @ Thu Sep 2 08:47:15 2021 +* Created by HDL4SE @ Thu Sep 2 18:50:33 2021 * Don't edit it. */ @@ -56,6 +56,8 @@ IDLIST VID(nwReset), VID(wRead_out), VID(bReadAddr_out), + VID(regrddata), + VID(regrddata2), VID(ram_dot_byteena), /* port:ram(ram8kb).byteena, 1 */ VID(ram_dot_wren), /* port:ram(ram8kb).wren, 4 */ VID(bReadDataRam), @@ -66,6 +68,14 @@ IDLIST VID(bWriteMask), VID(wRead), VID(bReadAddr), + VID(regno), + VID(regena), + VID(regwrdata), + VID(regwren), + VID(regno2), + VID(regena2), + VID(regwrdata2), + VID(regwren2), VID(bReadData), VID(ramaddr), END_IDLIST @@ -96,6 +106,8 @@ GEN_MODULE_INIT WIRE(ramaddr, 30); WIRE(wRead_out, 1); WIRE(bReadAddr_out, 32); + WIRE(regrddata, 32); + WIRE(regrddata2, 32); WIRE(ram_dot_byteena, 1); WIRE(ram_dot_wren, 1); WIRE(bReadDataRam, 32); @@ -106,6 +118,14 @@ GEN_MODULE_INIT WIRE(bWriteMask, 4); WIRE(wRead, 1); WIRE(bReadAddr, 32); + WIRE(regno, 5); + WIRE(regena, 4); + WIRE(regwrdata, 32); + WIRE(regwren, 1); + WIRE(regno2, 5); + WIRE(regena2, 4); + WIRE(regwrdata2, 32); + WIRE(regwren2, 1); CELL_INST("76FBFD4B-FEAD-45fd-AA27-AFC58AC241C2", /* hdl4se_reg */ "readcmd", "32'h1", @@ -114,6 +134,14 @@ GEN_MODULE_INIT "readaddr", "32'h20", "wClk, bReadAddr, bReadAddr_out"); + CELL_INST("2E577C6B-2FF1-425E-90B3-947EB523B863", /* regfile */ + "regs", + "", + "regno, regena, wClk, regwrdata, regwren, regrddata"); + CELL_INST("2E577C6B-2FF1-425E-90B3-947EB523B863", /* regfile */ + "regs2", + "", + "regno2, regena2, wClk, regwrdata2, regwren2, regrddata2"); CELL_INST("EE3409B2-6D04-42B3-A44D-7F2444DDC00D", /* ram8kb */ "ram", "", @@ -125,7 +153,9 @@ GEN_MODULE_INIT CELL_INST("638E8BC3-B0E0-41DC-9EDD-D35A39FD8051", /* riscv_core */ "core", "", - "wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask, wRead, bReadAddr, bReadData"); + "wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask, wRead, bReadAddr, bReadData" + ", regno, regena, regwrdata, regwren, regrddata, regno2, regena2, regwrdata2, regwren2" + ", regrddata2"); GEN_FUNC("ram_dot_byteena", top_gen_ram_dot_byteena); GEN_FUNC("ram_dot_wren", top_gen_ram_dot_wren); GEN_FUNC("bReadData", top_gen_bReadData); diff --git a/examples/hdl4se_riscv/test_code/console.c b/examples/hdl4se_riscv/test_code/console.c index d554224dc8856ae3094bbf9b0ab162c3c331bca0..880ebfc53c9b24e4853544e512592c0a28cdf0cf 100644 --- a/examples/hdl4se_riscv/test_code/console.c +++ b/examples/hdl4se_riscv/test_code/console.c @@ -1,6 +1,6 @@ #define UARTADDRESS (unsigned int *)0xf0000100 -#define REFFREQ 25000000 +#define REFFREQ 50000000 volatile unsigned int* _uartaddr = UARTADDRESS; volatile unsigned int _uartstate; diff --git a/examples/hdl4se_riscv/test_code/test.cod b/examples/hdl4se_riscv/test_code/test.cod index 146ea82325d4fa3a803b3bbd688493c3062e33bb..f32351b10bb44ef1b1e46eef78e7f24d69c15012 100644 --- a/examples/hdl4se_riscv/test_code/test.cod +++ b/examples/hdl4se_riscv/test_code/test.cod @@ -169,7 +169,7 @@ E3 90 07 FC 93 07 00 00 13 85 07 00 03 24 C1 01 83 27 84 FD 83 C7 07 00 E3 90 07 FA 93 07 00 00 13 85 07 00 03 24 C1 02 13 01 01 03 67 80 00 00 13 01 01 FE 23 2E 81 00 13 04 01 02 23 26 A4 FE -B7 87 7D 01 13 87 07 84 83 27 C4 FE 33 47 F7 02 +B7 F7 FA 02 13 87 07 08 83 27 C4 FE 33 47 F7 02 83 A7 01 C3 93 87 07 01 23 A0 E7 00 93 07 00 00 13 85 07 00 03 24 C1 01 13 01 01 02 67 80 00 00 13 01 01 EC 23 2E 11 12 23 2C 81 12 13 04 01 14 diff --git a/examples/hdl4se_riscv/test_code/test.elf b/examples/hdl4se_riscv/test_code/test.elf index 5c15f8b08e4670d2778c1c8de0bc670fc844e09d..cd023ee1436ca3044351d0b98a8f7669496ef4d3 100644 Binary files a/examples/hdl4se_riscv/test_code/test.elf and b/examples/hdl4se_riscv/test_code/test.elf differ diff --git a/examples/hdl4se_riscv/test_code/test.hex b/examples/hdl4se_riscv/test_code/test.hex index 7e4cc79bf03bc0b81a174040cf53eb608db6bf6e..7eb4f79fcfced628962c37d284c18835631db4a7 100644 --- a/examples/hdl4se_riscv/test_code/test.hex +++ b/examples/hdl4se_riscv/test_code/test.hex @@ -168,7 +168,7 @@ :100AE400832784FD83C70700E39007FA9307000078 :100AF400138507000324C10213010103678000006A :100B0400130101FE232E8100130401022326A4FEF7 -:100B1400B7877D01138707848327C4FE3347F70211 +:100B1400B7F7FA02138707088327C4FE3347F7029F :100B240083A701C39387070123A0E700930700006D :100B3400138507000324C10113010102678000002B :100B4400130101EC232E1112232C8112130401141E diff --git a/examples/hdl4se_riscv/test_code/test.info b/examples/hdl4se_riscv/test_code/test.info index 5ed4d6d4be917aab63e88b120860b4b0590ec5f7..2a97bf990edb7f8d891ea1ea2711f46dfea27c92 100644 --- a/examples/hdl4se_riscv/test_code/test.info +++ b/examples/hdl4se_riscv/test_code/test.info @@ -10,7 +10,7 @@ ELF Header: Version: 0x1 Entry point address: 0x8c Start of program headers: 52 (bytes into file) - Start of section headers: 8432 (bytes into file) + Start of section headers: 8428 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) @@ -32,10 +32,10 @@ Section Headers: [ 8] .sbss NOBITS 00002828 001828 000008 00 WA 0 0 4 [ 9] .bss NOBITS 00002830 001828 00001c 00 WA 0 0 4 [10] .comment PROGBITS 00000000 001828 000012 01 MS 0 0 1 - [11] .riscv.attributes RISCV_ATTRIBUTE 00000000 00183a 000026 00 0 0 1 - [12] .symtab SYMTAB 00000000 001860 000520 10 13 41 4 - [13] .strtab STRTAB 00000000 001d80 0002f2 00 0 0 1 - [14] .shstrtab STRTAB 00000000 002072 00007e 00 0 0 1 + [11] .riscv.attributes RISCV_ATTRIBUTE 00000000 00183a 000021 00 0 0 1 + [12] .symtab SYMTAB 00000000 00185c 000520 10 13 41 4 + [13] .strtab STRTAB 00000000 001d7c 0002f2 00 0 0 1 + [14] .shstrtab STRTAB 00000000 00206e 00007e 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), @@ -149,4 +149,4 @@ No version information found in this file. Attribute Section: riscv File Attributes Tag_RISCV_stack_align: 16-bytes - Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0" + Tag_RISCV_arch: "rv32i2p0_m2p0" diff --git a/examples/hdl4se_riscv/test_code/test.mif b/examples/hdl4se_riscv/test_code/test.mif index 95387be8e9e6144d5e56de512925f33742381c00..37506ce86227dabce864431d55d1ee68781dd356 100644 --- a/examples/hdl4se_riscv/test_code/test.mif +++ b/examples/hdl4se_riscv/test_code/test.mif @@ -713,8 +713,8 @@ BEGIN 02C2 : 00812E23; 02C3 : 02010413; 02C4 : FEA42623; -02C5 : 017D87B7; -02C6 : 84078713; +02C5 : 02FAF7B7; +02C6 : 08078713; 02C7 : FEC42783; 02C8 : 02F74733; 02C9 : C301A783; diff --git a/examples/hdl4se_riscv/test_code/test.txt b/examples/hdl4se_riscv/test_code/test.txt index f491894161a894e501da74ac460104f748298aa5..5c3278dc27d7825bf52f0ad368efefda40eb42a0 100644 --- a/examples/hdl4se_riscv/test_code/test.txt +++ b/examples/hdl4se_riscv/test_code/test.txt @@ -723,8 +723,8 @@ Disassembly of section .text: b08: 00812e23 sw x8,28(x2) b0c: 02010413 addi x8,x2,32 b10: fea42623 sw x10,-20(x8) - b14: 017d87b7 lui x15,0x17d8 - b18: 84078713 addi x14,x15,-1984 # 17d7840 <__global_pointer$+0x17d4c50> + b14: 02faf7b7 lui x15,0x2faf + b18: 08078713 addi x14,x15,128 # 2faf080 <__global_pointer$+0x2fac490> b1c: fec42783 lw x15,-20(x8) b20: 02f74733 div x14,x14,x15 b24: c301a783 lw x15,-976(x3) # 2820 <_uartaddr> @@ -1444,12 +1444,13 @@ Disassembly of section .comment: Disassembly of section .riscv.attributes: 00000000 <.riscv.attributes>: - 0: 2541 c.jal 680 <_s2d+0x4> + 0: 2041 c.jal 80 2: 0000 c.unimp 4: 7200 c.flw f8,32(x12) 6: 7369 c.lui x6,0xffffa 8: 01007663 bgeu x0,x16,14 - c: 0000001b 0x1b + c: 0016 c.slli x0,0x5 + e: 0000 c.unimp 10: 1004 c.addi4spn x9,x2,32 12: 7205 c.lui x4,0xfffe1 14: 3376 c.fldsp f6,376(x2) @@ -1458,4 +1459,4 @@ Disassembly of section .riscv.attributes: 1a: 5f30 c.lw x12,120(x14) 1c: 326d c.jal fffff9c6 <__global_pointer$+0xffffcdd6> 1e: 3070 c.fld f12,224(x8) - 20: 615f 7032 0030 0x307032615f + ... diff --git a/examples/hdl4se_riscv/verilog/riscv_core_v4.v b/examples/hdl4se_riscv/verilog/riscv_core_v4.v index 1bf3c8c59b468400b1a8d445707357ee04a6dbc8..b4af98465debb08de7744dd4d66754e2140e4769 100644 --- a/examples/hdl4se_riscv/verilog/riscv_core_v4.v +++ b/examples/hdl4se_riscv/verilog/riscv_core_v4.v @@ -29,13 +29,19 @@ ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF ** THE POSSIBILITY OF SUCH DAMAGE. */ -/* riscv_core_v4.v */ +/* riscv_core_v2.v */ -`define RISCVSTATE_STARTUP 0 -`define RISCVSTATE_EXEC_INST 1 -`define RISCVSTATE_WAIT_LD 2 -`define RISCVSTATE_WAIT_ST 3 -`define RISCVSTATE_WAIT_DIV 4 +`define RISCVSTATE_INIT_REGX1 0 +`define RISCVSTATE_INIT_REGX2 1 +`define RISCVSTATE_READ_INST 2 +`define RISCVSTATE_READ_REGS 3 +`define RISCVSTATE_EXEC_INST 4 +`define RISCVSTATE_WRITE_RD 5 +`define RISCVSTATE_WAIT_LD 6 +`define RISCVSTATE_WAIT_LD2 7 +`define RISCVSTATE_WAIT_ST 8 +`define RISCVSTATE_WAIT_ST2 9 +`define RISCVSTATE_WAIT_DIV 10 `define RAMSIZE 4096 @@ -52,77 +58,46 @@ module riscv_core( output [3:0] bWriteMask, output reg wRead, output reg [31:0] bReadAddr, - input [31:0] bReadData + input [31:0] bReadData, + output reg [4:0] regno, + output reg [3:0] regena, + output reg [31:0] regwrdata, + output reg regwren, + input [31:0] regrddata, + output reg [4:0] regno2, + output reg [3:0] regena2, + output reg [31:0] regwrdata2, + output reg regwren2, + input [31:0] regrddata2 ); - reg [31:0] pc; - - reg [31:0] x1; - reg [31:0] x2; - reg [31:0] x3; - reg [31:0] x4; - reg [31:0] x5; - reg [31:0] x6; - reg [31:0] x7; - reg [31:0] x8; - reg [31:0] x9; - reg [31:0] x10; - reg [31:0] x11; - reg [31:0] x12; - reg [31:0] x13; - reg [31:0] x14; - reg [31:0] x15; - reg [31:0] x16; - reg [31:0] x17; - reg [31:0] x18; - reg [31:0] x19; - reg [31:0] x20; - reg [31:0] x21; - reg [31:0] x22; - reg [31:0] x23; - reg [31:0] x24; - reg [31:0] x25; - reg [31:0] x26; - reg [31:0] x27; - reg [31:0] x28; - reg [31:0] x29; - reg [31:0] x30; - reg [31:0] x31; - - reg [3:0] state; - - reg [31:0] imm; - reg [4:0] dstreg; - reg [31:0] dstvalue; + reg [31:0] pc; //GREG(pc, 32, riscv_core_reg_gen_pc); + reg [31:0] instr; //GREG(instr, 32, riscv_core_reg_gen_instr); + reg write; //GREG(write, 1, riscv_core_gen_write); + reg [31:0] writeaddr; //GREG(writeaddr, 32, riscv_core_gen_write); + reg [31:0] writedata; //GREG(writedata, 32, riscv_core_gen_write); + reg [3:0] writemask; //GREG(writemask, 4, riscv_core_gen_write); + reg [4:0] readreg; //GREG(readreg, 5, riscv_core_reg_gen_readreg); + reg [3:0] state; //GREG(state, 4, riscv_core_gen_state); + reg [31:0] imm; //GREG(imm, 32, riscv_core_gen_imm); + reg [4:0] dstreg; //GREG(dstreg, 5, riscv_core_gen_dstreg); + reg [31:0] dstvalue; //GREG(dstvalue, 32, riscv_core_gen_dstreg); + reg [31:0] ldaddr; //GREG(ldaddr, 2, riscv_core_gen_ldaddr); reg [4:0] divclk; - - reg write; - reg [31:0] writeaddr; - reg [31:0] writedata; - reg [3:0] writemask; - + reg [31:0] lastv; + reg [31:0] lastaddr; assign wWrite = write; assign bWriteAddr = writeaddr; assign bWriteData = writedata; assign bWriteMask = writemask; - reg [31:0] cur_instr; - always @(posedge wClk) - if (state == `RISCVSTATE_EXEC_INST) - cur_instr <= bReadData; - - wire [31:0] instr = bReadData; - wire [4:0] rs1_no = instr[19:15]; - wire [4:0] rs2_no = instr[24:20]; - wire [4:0] opcode = instr[6:2]; - wire [4:0] rd = instr[11:7]; - wire [2:0] func3 = instr[14:12]; - wire [4:0] rd_r = cur_instr[11:7]; - wire [2:0] func3_r = cur_instr[14:12]; + wire [4:0] opcode = instr[6:2]; + wire [4:0] rd = instr[11:7]; + wire [2:0] func3 = instr[14:12]; reg cond; - reg [31:0] rs1; - reg [31:0] rs2; + wire [31:0] rs1 = regrddata; + wire [31:0] rs2 = regrddata2; wire signed [31:0] rs1_s = rs1; wire signed [31:0] rs2_s = rs2; wire signed [31:0] imm_s = imm; @@ -147,127 +122,6 @@ module riscv_core( assign mod_result = mod_result_r; assign mods_result = mods_result_r; - always @(rs1_no or x31 or - x1 or x2 or x3 or x4 or x5 or x6 or x7 or x8 or x9 or x10 or - x11 or x12 or x13 or x14 or x15 or x16 or x17 or x18 or x19 or x20 or - x21 or x22 or x23 or x24 or x25 or x26 or x27 or x28 or x29 or x30 - ) - case (rs1_no) - 5'd0: rs1 = 0; - 5'd1: rs1 = x1; - 5'd2: rs1 = x2; - 5'd3: rs1 = x3; - 5'd4: rs1 = x4; - 5'd5: rs1 = x5; - 5'd6: rs1 = x6; - 5'd7: rs1 = x7; - 5'd8: rs1 = x8; - 5'd9: rs1 = x9; - 5'd10: rs1 = x10; - 5'd11: rs1 = x11; - 5'd12: rs1 = x12; - 5'd13: rs1 = x13; - 5'd14: rs1 = x14; - 5'd15: rs1 = x15; - 5'd16: rs1 = x16; - 5'd17: rs1 = x17; - 5'd18: rs1 = x18; - 5'd19: rs1 = x19; - 5'd20: rs1 = x20; - 5'd21: rs1 = x21; - 5'd22: rs1 = x22; - 5'd23: rs1 = x23; - 5'd24: rs1 = x24; - 5'd25: rs1 = x25; - 5'd26: rs1 = x26; - 5'd27: rs1 = x27; - 5'd28: rs1 = x28; - 5'd29: rs1 = x29; - 5'd30: rs1 = x30; - 5'd31: rs1 = x31; - endcase - - always @(rs2_no or x31 or - x1 or x2 or x3 or x4 or x5 or x6 or x7 or x8 or x9 or x10 or - x11 or x12 or x13 or x14 or x15 or x16 or x17 or x18 or x19 or x20 or - x21 or x22 or x23 or x24 or x25 or x26 or x27 or x28 or x29 or x30 - ) - case (rs2_no) - 5'd0: rs2 = 0; - 5'd1: rs2 = x1; - 5'd2: rs2 = x2; - 5'd3: rs2 = x3; - 5'd4: rs2 = x4; - 5'd5: rs2 = x5; - 5'd6: rs2 = x6; - 5'd7: rs2 = x7; - 5'd8: rs2 = x8; - 5'd9: rs2 = x9; - 5'd10: rs2 = x10; - 5'd11: rs2 = x11; - 5'd12: rs2 = x12; - 5'd13: rs2 = x13; - 5'd14: rs2 = x14; - 5'd15: rs2 = x15; - 5'd16: rs2 = x16; - 5'd17: rs2 = x17; - 5'd18: rs2 = x18; - 5'd19: rs2 = x19; - 5'd20: rs2 = x20; - 5'd21: rs2 = x21; - 5'd22: rs2 = x22; - 5'd23: rs2 = x23; - 5'd24: rs2 = x24; - 5'd25: rs2 = x25; - 5'd26: rs2 = x26; - 5'd27: rs2 = x27; - 5'd28: rs2 = x28; - 5'd29: rs2 = x29; - 5'd30: rs2 = x30; - 5'd31: rs2 = x31; - endcase - - always@(posedge wClk) - if (~nwReset) begin - x1 <= 32'h0000008c; - x2 <= `RAMSIZE * 4 - 16; - end - else - case (dstreg) - 5'd0: ;//0 <= dstvalue; - 5'd1: x1 <= dstvalue; - 5'd2: x2 <= dstvalue; - 5'd3: x3 <= dstvalue; - 5'd4: x4 <= dstvalue; - 5'd5: x5 <= dstvalue; - 5'd6: x6 <= dstvalue; - 5'd7: x7 <= dstvalue; - 5'd8: x8 <= dstvalue; - 5'd9: x9 <= dstvalue; - 5'd10: x10 <= dstvalue; - 5'd11: x11 <= dstvalue; - 5'd12: x12 <= dstvalue; - 5'd13: x13 <= dstvalue; - 5'd14: x14 <= dstvalue; - 5'd15: x15 <= dstvalue; - 5'd16: x16 <= dstvalue; - 5'd17: x17 <= dstvalue; - 5'd18: x18 <= dstvalue; - 5'd19: x19 <= dstvalue; - 5'd20: x20 <= dstvalue; - 5'd21: x21 <= dstvalue; - 5'd22: x22 <= dstvalue; - 5'd23: x23 <= dstvalue; - 5'd24: x24 <= dstvalue; - 5'd25: x25 <= dstvalue; - 5'd26: x26 <= dstvalue; - 5'd27: x27 <= dstvalue; - 5'd28: x28 <= dstvalue; - 5'd29: x29 <= dstvalue; - 5'd30: x30 <= dstvalue; - 5'd31: x31 <= dstvalue; - endcase - /* cond */ always @(rs1 or rs2 or rs1_s or rs2_s or func3) case(func3) @@ -279,289 +133,468 @@ module riscv_core( 7:/*bgeu*/cond = rs1 >= rs2; default: cond = 1'b0; endcase - - always @(instr) - case (instr[6:2]) - 5'h0d: imm = {instr[31:12], 12'b0}; - 5'h05: imm = {instr[31:12], 12'b0}; - 5'h1b: imm = {{12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0}; - 5'h19: imm = {{20{instr[31]}}, instr[31:20]}; - 5'h18: imm = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0}; - 5'h00: imm = {{20{instr[31]}}, instr[31:20]}; - 5'h08: imm = {{20{instr[31]}}, instr[31:25], instr[11:7]}; - 5'h04: imm = {{20{instr[31]}}, instr[31:20]}; - default: imm = 0; - endcase - - - /* state */ + + //DEFINE_FUNC(riscv_core_reg_gen_lastv, "state, instr, ldaddr") { always @(posedge wClk) - if (!nwReset) begin - state <= `RISCVSTATE_STARTUP; - end else begin - case (state) - `RISCVSTATE_STARTUP: state <= `RISCVSTATE_EXEC_INST; - `RISCVSTATE_EXEC_INST: begin - if (opcode == 5'h00) - state <= `RISCVSTATE_WAIT_LD; - else if (opcode == 5'h08) - state <= `RISCVSTATE_WAIT_ST; - else if (opcode == 5'h0c && instr[25] && func3[2] && (rs2 != 0)) begin - state <= `RISCVSTATE_WAIT_DIV; - divclk <= 11; - end + if (state == `RISCVSTATE_WAIT_LD) begin + lastaddr <= ldaddr; + if (func3 == 1 && ldaddr[1:0] == 3) begin /* lh */ + lastv <= {24'b0, bReadData[31:24]}; end - `RISCVSTATE_WAIT_LD: state <= `RISCVSTATE_EXEC_INST; - `RISCVSTATE_WAIT_ST: state <= `RISCVSTATE_EXEC_INST; - `RISCVSTATE_WAIT_DIV: begin - if (divclk == 0) - state <= `RISCVSTATE_EXEC_INST; + else if (func3 == 2 && ldaddr[1:0] != 0) begin /* lw */ + if (ldaddr[1:0] == 1) + lastv <= {8'b0, bReadData[31:8]}; + else if (ldaddr[1:0] == 2) + lastv <= {16'b0, bReadData[31:16]}; else - divclk <= divclk - 1; + lastv <= {24'b0, bReadData[31:24]}; end - endcase - end - - reg [31:0] newpc; - always @(state or pc or rs1 or imm or cond or opcode) - if (state == `RISCVSTATE_EXEC_INST) begin - case (opcode) - 5'h1b: newpc = pc + imm; - 5'h19: newpc = rs1 + imm; - 5'h18: newpc = cond ? pc + imm : pc + 4; - default: newpc = pc + 4; - endcase - end else begin - newpc = pc; + else if (func3 == 5 && ldaddr[1:0] == 3) begin /* lhu */ + lastv <= {24'b0, bReadData[31:24]}; + end + end else if (state == `RISCVSTATE_EXEC_INST) begin + lastaddr <= rs1 + imm; + lastv <= rs2; end - - /* pc */ + + //DEFINE_FUNC(riscv_core_reg_gen_pc, "nwReset, state, instr, pc, rs1, imm, regrddata") { always @(posedge wClk) if (!nwReset) begin pc <= 32'h00000074; end else begin - pc <= newpc; - end - - /* read and readaddr */ - always @(state or pc or opcode or imm or rs1 or nwReset) - if (~nwReset) begin - wRead = 0; - bReadAddr = 0; - end else begin - wRead = 1; - bReadAddr = newpc; if (state == `RISCVSTATE_EXEC_INST) begin - if (opcode == 5'h00) begin /*LOAD*/ - wRead = 1; - bReadAddr = rs1 + imm; - end else if (opcode == 5'h08) begin /*STORE*/ - wRead = 0; - bReadAddr = 0; - end + case (opcode) + 5'h1b: pc <= pc + imm; + 5'h19: pc <= rs1 + imm; + 5'h18: pc <= cond ? pc + imm : pc + 4; + default: pc <= pc + 4; + endcase end end - wire [31:0] newwriteaddr = rs1 + imm; + //DEFINE_FUNC(riscv_core_reg_gen_instr, "state, bReadData") { + always @(posedge wClk) + if (state == `RISCVSTATE_READ_REGS) + instr <= bReadData; - /* write */ - always @(nwReset or state or opcode or newwriteaddr or rs1 or imm or rs2) - begin - write = 0; - writeaddr = 0; - writemask = 0; - writedata = 0; - if (nwReset && (state == `RISCVSTATE_EXEC_INST) && (opcode == 5'h08)) begin - /* riscv支持地址不对齐访问,但是假定写在一个32位字中 */ - writeaddr = newwriteaddr; - writemask = 4'h0; - writedata = rs2; - write = 1'b1; + //DEFINE_FUNC(riscv_core_reg_gen_readreg, "state, instr") { + always @(posedge wClk) + if (state == `RISCVSTATE_EXEC_INST) + if (opcode == 5'h00) + readreg <= rd; + + wire [31:0] newwriteaddr = rs1 + imm; + //DEFINE_FUNC(riscv_core_gen_write, "nwReset, state, pc, instr, rs1, regrddata, imm") { + always @(posedge wClk) + if (!nwReset) begin + write <= 0; + end else if (state == `RISCVSTATE_EXEC_INST) begin + write <= 0; + if (opcode == 5'h08) begin + + writeaddr <= newwriteaddr; + writemask <= 4'h0; + writedata <= rs2; + write <= 1'b1; case (func3) 0:/*sb*/ begin case (newwriteaddr[1:0]) 0: begin - writemask = 4'he; - writedata = rs2; + writemask <= 4'he; + writedata <= rs2; end 1: begin - writemask = 4'hd; - writedata = {rs2[23:0], 8'h0}; + writemask <= 4'hd; + writedata <= {rs2[23:0], 8'h0}; end 2: begin - writemask = 4'hb; - writedata = {rs2[15:0], 16'h0}; + writemask <= 4'hb; + writedata <= {rs2[15:0], 16'h0}; end 3: begin - writemask = 4'h7; - writedata = {rs2[7:0], 24'h0}; + writemask <= 4'h7; + writedata <= {rs2[7:0], 24'h0}; end endcase end 1:/*sh*/ begin case (newwriteaddr[1:0]) 0: begin - writemask = 4'hc; - writedata = rs2; + writemask <= 4'hc; + writedata <= rs2; end 1: begin - writemask = 4'h9; - writedata = {rs2[23:0], 8'h0}; + writemask <= 4'h9; + writedata <= {rs2[23:0], 8'h0}; end 2: begin - writemask = 4'h3; - writedata = {rs2[15:0], 16'h0}; + writemask <= 4'h3; + writedata <= {rs2[15:0], 16'h0}; + end + 3: begin + writemask <= 4'h7; + writedata <= {rs2[7:0], 24'h0}; + end + endcase + end + 2:/*sw*/ begin + case (newwriteaddr[1:0]) + 0: begin + writemask <= 4'h0; + writedata <= rs2; + end + 1: begin + writemask <= 4'h1; + writedata <= {rs2[23:0], 8'h0}; + end + 2: begin + writemask <= 4'h3; + writedata <= {rs2[15:0], 16'h0}; + end + 3: begin + writemask <= 4'h7; + writedata <= {rs2[7:0], 24'h0}; end endcase end endcase end + end else if (state == `RISCVSTATE_WAIT_ST) begin + write <= 0; + writeaddr <= lastaddr + 4; + if (opcode == 5'h08) begin + case (func3) + 1:/*sh*/ begin + case (lastaddr[1:0]) + 3: begin + writemask <= 4'he; + writedata <= {24'b0, lastv[31:24]}; + write <= 1; + end + endcase + end + 2:/*sw*/ begin + case (lastaddr[1:0]) + 1: begin + writemask <= 4'he; + writedata <= {24'b0, lastv[31:24]}; + write <= 1; + end + 2: begin + writemask <= 4'hc; + writedata <= {16'b0, lastv[31:16]}; + write <= 1; + end + 3: begin + writemask <= 4'h8; + writedata <= {8'b0, lastv[31:8]}; + write <= 1; + end + endcase + end + endcase + end + end else begin + write <= 0; end - reg [31:0] ldaddr; + //DEFINE_FUNC(riscv_core_gen_state, "state, instr, nwReset") { + always @(posedge wClk) + if (!nwReset) begin + state <= `RISCVSTATE_INIT_REGX1; + end else begin + case (state) + `RISCVSTATE_INIT_REGX1: state <= `RISCVSTATE_INIT_REGX2; + `RISCVSTATE_INIT_REGX2: state <= `RISCVSTATE_READ_INST; + `RISCVSTATE_READ_INST: state <= `RISCVSTATE_READ_REGS; + `RISCVSTATE_READ_REGS: state <= `RISCVSTATE_EXEC_INST; + `RISCVSTATE_WRITE_RD: state <= `RISCVSTATE_READ_INST; + `RISCVSTATE_EXEC_INST: begin + if (opcode == 5'h00) + state <= `RISCVSTATE_WAIT_LD; + else if (opcode == 5'h08) + state <= `RISCVSTATE_WAIT_ST; + else if (opcode == 5'h0c && instr[25] && func3[2] && (rs2 != 0)) begin + state <= `RISCVSTATE_WAIT_DIV; + divclk <= 11; + end else + state <= `RISCVSTATE_WRITE_RD; + end + `RISCVSTATE_WAIT_LD: begin + if (func3 == 1 && ldaddr[1:0] == 3) begin /* lh */ + state <= `RISCVSTATE_WAIT_LD2; + end + else if (func3 == 2 && ldaddr[1:0] != 0) begin /* lw */ + state <= `RISCVSTATE_WAIT_LD2; + end + else if (func3 == 5 && ldaddr[1:0] == 3) begin /* lhu */ + state <= `RISCVSTATE_WAIT_LD2; + end + else begin + state <= `RISCVSTATE_WRITE_RD; + end + end + `RISCVSTATE_WAIT_LD2: state <= `RISCVSTATE_WRITE_RD; + `RISCVSTATE_WAIT_ST: begin + state <= `RISCVSTATE_READ_INST; + if (opcode == 5'h08) begin + if (func3 == 1 && (lastaddr & 3) == 3) begin /* sh */ + state <= `RISCVSTATE_WAIT_ST2; + end + else if (func3 == 2 && (lastaddr & 3) != 0) begin + state <= `RISCVSTATE_WAIT_ST2; + end + end + end + `RISCVSTATE_WAIT_ST2: state <= `RISCVSTATE_READ_INST; + `RISCVSTATE_WAIT_DIV: begin + if (divclk == 0) + state <= `RISCVSTATE_WRITE_RD; + else + divclk <= divclk - 1; + end + endcase + end + //DEFINE_FUNC(riscv_core_gen_imm, "bReadData, state") { + /* 在RISCVSTATE_READ_REGS周期生成imm */ always @(posedge wClk) - if (state == `RISCVSTATE_EXEC_INST) begin - ldaddr <= rs1 + imm; + if (state == `RISCVSTATE_READ_REGS) begin + case (bReadData[6:2]) + 5'h0d: imm <= {bReadData[31:12], 12'b0}; + 5'h05: imm <= {bReadData[31:12], 12'b0}; + 5'h1b: imm <= {{12{bReadData[31]}}, bReadData[19:12], bReadData[20], bReadData[30:21], 1'b0}; + 5'h19: imm <= {{20{bReadData[31]}}, bReadData[31:20]}; + 5'h18: imm <= {{20{bReadData[31]}}, bReadData[7], bReadData[30:25], bReadData[11:8], 1'b0}; + 5'h00: imm <= {{20{bReadData[31]}}, bReadData[31:20]}; + 5'h08: imm <= {{20{bReadData[31]}}, bReadData[31:25], bReadData[11:7]}; + 5'h04: imm <= {{20{bReadData[31]}}, bReadData[31:20]}; + endcase end - always @(state or ldaddr or func3_r or rd_r or bReadData or divclk or imm or pc or rs1 or rs2 or instr) begin - dstvalue = 0; - dstreg = 0; + //DEFINE_FUNC(riscv_core_reg_wr_sig, "state, dstreg, dstvalue, bReadData, instr, regrddata, pc") { + always @(state or dstreg or dstvalue or bReadData or instr or regrddata or regrddata2 or pc) + case (state) + `RISCVSTATE_READ_REGS: begin + regno = bReadData[19:15]; /* instr */ + regwren = 0; + regena = 0; + regwrdata = 0; + regno2 = bReadData[24:20]; /* instr */ + regwren2 = 0; + regena2 = 0; + regwrdata2 = 0; + end + `RISCVSTATE_WRITE_RD: begin + regwren = (dstreg != 0) ? 1 : 0; + regno = dstreg; + regena = 4'hf; + regwrdata = dstvalue; + regwren2 = (dstreg != 0) ? 1 : 0; + regno2 = dstreg; + regena2 = 4'hf; + regwrdata2 = dstvalue; + end + `RISCVSTATE_INIT_REGX1: begin + regwren = 1; + regno = 1; + regena = 4'hf; + regwrdata = 32'h8c; + regwren2 = 1; + regno2 = 1; + regena2 = 4'hf; + regwrdata2 = 32'h8c; + end + `RISCVSTATE_INIT_REGX2: begin + regwren = 1; + regno = 2; + regena = 4'hf; + regwrdata = `RAMSIZE * 4 - 16; + regwren2 = 1; + regno2 = 2; + regena2 = 4'hf; + regwrdata2 = `RAMSIZE * 4 - 16; + end + default: begin + regwren = 0; + regno = 0; + regena = 0; + regwrdata = 0; + regwren2 = 0; + regno2 = 0; + regena2 = 0; + regwrdata2 = 0; + end + endcase + + //DEFINE_FUNC(riscv_core_gen_ldaddr, "state, pc, instr, rs1") { + always @(posedge wClk) + if (state == `RISCVSTATE_READ_INST) begin + ldaddr <= pc; + end else if (state == `RISCVSTATE_EXEC_INST) begin + if (opcode == 5'h00) begin + /* ld inst */ + ldaddr <= rs1 + imm; + end + end + + //DEFINE_FUNC(riscv_core_gen_dstreg, "state, instr, ldaddr, readreg, bReadData, pc, rs1, regrddata, imm") { + always @(posedge wClk) case (state) `RISCVSTATE_WAIT_LD: begin - dstreg = rd_r; - case (func3_r) + dstreg <= readreg; + case (func3) 0: begin case (ldaddr[1:0]) - 0: dstvalue = {{24{bReadData[7]}}, bReadData[7:0]}; - 1: dstvalue = {{24{bReadData[15]}}, bReadData[15:8]}; - 2: dstvalue = {{24{bReadData[23]}}, bReadData[23:16]}; - 3: dstvalue = {{24{bReadData[31]}}, bReadData[31:24]}; + 0: dstvalue <= {{24{bReadData[7]}}, bReadData[7:0]}; + 1: dstvalue <= {{24{bReadData[15]}}, bReadData[15:8]}; + 2: dstvalue <= {{24{bReadData[23]}}, bReadData[23:16]}; + 3: dstvalue <= {{24{bReadData[31]}}, bReadData[31:24]}; endcase end 1: begin case (ldaddr[1:0]) - 0: dstvalue = {{16{bReadData[15]}}, bReadData[15:0]}; - 1: dstvalue = {{16{bReadData[23]}}, bReadData[23:8]}; - 2: dstvalue = {{16{bReadData[31]}}, bReadData[31:16]}; - 3: dstvalue = 32'hdeadbeef; + 0: dstvalue <= {{16{bReadData[15]}}, bReadData[15:0]}; + 1: dstvalue <= {{16{bReadData[23]}}, bReadData[23:8]}; + 2: dstvalue <= {{16{bReadData[31]}}, bReadData[31:16]}; + 3: dstvalue <= 32'hdeadbeef; endcase end - 2: dstvalue = bReadData; + 2: dstvalue <= bReadData; 4: begin case (ldaddr[1:0]) - 0: dstvalue = {24'b0, bReadData[7:0]}; - 1: dstvalue = {24'b0, bReadData[15:8]}; - 2: dstvalue = {24'b0, bReadData[23:16]}; - 3: dstvalue = {24'b0, bReadData[31:24]}; + 0: dstvalue <= {24'b0, bReadData[7:0]}; + 1: dstvalue <= {24'b0, bReadData[15:8]}; + 2: dstvalue <= {24'b0, bReadData[23:16]}; + 3: dstvalue <= {24'b0, bReadData[31:24]}; endcase end 5: begin case (ldaddr[1:0]) - 0: dstvalue = {16'b0, bReadData[15:0]}; - 1: dstvalue = {16'b0, bReadData[23:8]}; - 2: dstvalue = {16'b0, bReadData[31:16]}; - 3: dstvalue = 32'hdeadbeef; + 0: dstvalue <= {16'b0, bReadData[15:0]}; + 1: dstvalue <= {16'b0, bReadData[23:8]}; + 2: dstvalue <= {16'b0, bReadData[31:16]}; + 3: dstvalue <= 32'hdeadbeef; endcase end endcase end + `RISCVSTATE_WAIT_LD2: begin + dstreg <= rd; + if (func3 == 1 && ldaddr[1:0] == 3) begin + dstvalue <= {{16{bReadData[7]}}, bReadData[7:0], lastv[7:0]}; + end + else if (func3 == 2 && ldaddr[1:0] != 0) begin + if (ldaddr[1:0] == 1) + dstvalue <= {bReadData[7:0], lastv[23:0]}; + else if (ldaddr[1:0] == 2) + dstvalue <= {bReadData[15:0], lastv[15:0]}; + else if (ldaddr[1:0] == 3) + dstvalue <= {bReadData[23:0], lastv[7:0]}; + end + else if (func3 == 5 && ldaddr[1:0] == 3) begin + dstvalue <= {16'b0, bReadData[7:0], lastv[7:0]}; + end else begin + dstreg <= 0; + dstvalue <= 0; + end + end `RISCVSTATE_WAIT_DIV: if (divclk == 0) begin - case (func3_r[1:0]) + dstreg <= 0; + case (func3[1:0]) 0: begin //div - dstreg = rd_r; - dstvalue = divs_result; + dstreg <= rd; + dstvalue <= divs_result; end 1: begin //divu - dstreg = rd_r; - dstvalue = div_result; + dstreg <= rd; + dstvalue <= div_result; end 2: begin//rem - dstreg = rd_r; - dstvalue = mods_result; + dstreg <= rd; + dstvalue <= mods_result; end 3: begin //remu - dstreg = rd_r; - dstvalue = mod_result; + dstreg <= rd; + dstvalue <= mod_result; end endcase end `RISCVSTATE_EXEC_INST: begin - dstreg = rd; + dstreg <= rd; case (opcode) 5'h0d: begin - dstvalue = imm; + dstvalue <= imm; end 5'h05: begin - dstvalue = imm + pc; + dstvalue <= imm + pc; end 5'h1b: begin - dstvalue = pc + 4; + dstvalue <= pc + 4; end 5'h19: begin - dstvalue = pc + 4; + dstvalue <= pc + 4; end 5'h04: begin /* alui */ case (func3) - 0:/*addi*/ dstvalue = rs1 + imm; - 1:/*slli*/ dstvalue = rs1 << imm[4:0]; - 2:/*slti*/ dstvalue = (rs1_s < imm_s) ? 1 : 0; - 3:/*sltiu*/dstvalue = (rs1 < imm) ? 1 : 0; - 4:/*xori*/ dstvalue = rs1 ^ imm; + 0:/*addi*/ dstvalue <= rs1 + imm; + 1:/*slli*/ dstvalue <= rs1 << imm[4:0]; + 2:/*slti*/ dstvalue <= (rs1_s < imm_s) ? 1 : 0; + 3:/*sltiu*/dstvalue <= (rs1 < imm) ? 1 : 0; + 4:/*xori*/ dstvalue <= rs1 ^ imm; 5:/*srli/srai*/ - dstvalue = instr[30] ? (rs1_s >> imm[4:0]) : (rs1 >> imm[4:0]); - 6:/*ori*/ dstvalue = rs1 | imm; - 7:/*andi*/ dstvalue = rs1 & imm; - default: begin dstreg = 0; dstvalue=0; end + dstvalue <= instr[30] ? (rs1_s >> imm[4:0]) : (rs1 >> imm[4:0]); + 6:/*ori*/ dstvalue <= rs1 | imm; + 7:/*andi*/ dstvalue <= rs1 & imm; + default: begin dstreg <= 0; dstvalue<=0; end endcase end 5'h0c: begin /*alu*/ if (instr[25]) begin /* is MUL/DIV instr*/ case (func3) 0: begin //mul - dstvalue = muls_result[31:0]; + dstvalue <= muls_result[31:0]; end 1: begin //mulh - dstvalue = muls_result[63:32]; + dstvalue <= muls_result[63:32]; end 2: begin //mulhsu - dstvalue = mulsu_result[63:32]; + dstvalue <= mulsu_result[63:32]; end 3: begin //mulhu - dstvalue = mul_result[63:32]; + dstvalue <= mul_result[63:32]; end 4: begin //div if (rs2 == 0) begin - dstvalue = 32'hffffffff; + dstvalue <= 32'hffffffff; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end 5: begin //divu if (rs2 == 0) begin - dstvalue = 32'hffffffff; + dstvalue <= 32'hffffffff; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end 6: begin//rem if (rs2 == 0) begin - dstvalue = rs1; + dstvalue <= rs1; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end 7: begin //remu if (rs2 == 0) begin - dstvalue = rs1; + dstvalue <= rs1; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end endcase @@ -569,44 +602,76 @@ module riscv_core( case (func3) 0: begin if (instr[30]) - dstvalue = sub_result; + dstvalue <= sub_result; else - dstvalue = add_result; + dstvalue <= add_result; end 1: begin //sll - dstvalue = rs1 << rs2[4:0]; + dstvalue <= rs1 << rs2[4:0]; end 2: begin //slt - dstvalue = (rs1_s < rs2_s) ? 1 : 0; + dstvalue <= (rs1_s < rs2_s) ? 1 : 0; end 3: begin //sltu - dstvalue = (rs1 < rs2) ? 1 : 0; + dstvalue <= (rs1 < rs2) ? 1 : 0; end 4: begin //xor - dstvalue = rs1 ^ rs2; + dstvalue <= rs1 ^ rs2; end 5: begin //srl/sra if (instr[30]) - dstvalue = rs1 >> rs2[4:0]; + dstvalue <= rs1 >> rs2[4:0]; else - dstvalue = rs1_s >> rs2[4:0]; + dstvalue <= rs1_s >> rs2[4:0]; end 6: begin //or - dstvalue = rs1 | rs2; + dstvalue <= rs1 | rs2; end 7: begin //and - dstvalue = rs1 & rs2; + dstvalue <= rs1 & rs2; end endcase end end default: begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end endcase end endcase + + //DEFINE_FUNC(riscv_core_read_sig, "state, pc, instr, bReadData, rs1") { + always @(state or pc or opcode or imm or rs1) begin + wRead = 0; + bReadAddr = 0; + if (state == `RISCVSTATE_READ_INST) begin + wRead = 1; + bReadAddr = pc; + end else if (state == `RISCVSTATE_EXEC_INST) begin + if (opcode == 5'h00) begin + /* ld inst */ + bReadAddr = rs1 + imm; + wRead = 1; + end + end else if (state == `RISCVSTATE_WAIT_LD) begin + if (func3 == 1 && (ldaddr & 3) == 3) begin /* lh */ + wRead = 1; + bReadAddr = ldaddr + 4; + end + else if (func3 == 2 && (ldaddr & 3) != 0) begin /* lw */ + wRead = 1; + bReadAddr = ldaddr + 4; + end + else if (func3 == 5 && (ldaddr & 3) == 3) begin /* lhu */ + wRead = 1; + bReadAddr = ldaddr + 4; + end + else begin + wRead = 0; + bReadAddr = 0; + end + end end endmodule \ No newline at end of file diff --git a/examples/hdl4se_riscv/verilog/riscv_core_v4_1.v b/examples/hdl4se_riscv/verilog/riscv_core_v4_1.v new file mode 100644 index 0000000000000000000000000000000000000000..1bf3c8c59b468400b1a8d445707357ee04a6dbc8 --- /dev/null +++ b/examples/hdl4se_riscv/verilog/riscv_core_v4_1.v @@ -0,0 +1,612 @@ + +/* +** HDL4SE: 软件Verilog综合仿真平台 +** Copyright (C) 2021-2021, raoxianhong +** LCOM: 轻量级组件对象模型 +** Copyright (C) 2021-2021, raoxianhong +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* riscv_core_v4.v */ + +`define RISCVSTATE_STARTUP 0 +`define RISCVSTATE_EXEC_INST 1 +`define RISCVSTATE_WAIT_LD 2 +`define RISCVSTATE_WAIT_ST 3 +`define RISCVSTATE_WAIT_DIV 4 + +`define RAMSIZE 4096 + +(* + HDL4SE="LCOM", + CLSID="638E8BC3-B0E0-41DC-9EDD-D35A39FD8051", + softmodule="hdl4se" +*) +module riscv_core( + input wClk, nwReset, + output wWrite, + output [31:0] bWriteAddr, + output [31:0] bWriteData, + output [3:0] bWriteMask, + output reg wRead, + output reg [31:0] bReadAddr, + input [31:0] bReadData + ); + + reg [31:0] pc; + + reg [31:0] x1; + reg [31:0] x2; + reg [31:0] x3; + reg [31:0] x4; + reg [31:0] x5; + reg [31:0] x6; + reg [31:0] x7; + reg [31:0] x8; + reg [31:0] x9; + reg [31:0] x10; + reg [31:0] x11; + reg [31:0] x12; + reg [31:0] x13; + reg [31:0] x14; + reg [31:0] x15; + reg [31:0] x16; + reg [31:0] x17; + reg [31:0] x18; + reg [31:0] x19; + reg [31:0] x20; + reg [31:0] x21; + reg [31:0] x22; + reg [31:0] x23; + reg [31:0] x24; + reg [31:0] x25; + reg [31:0] x26; + reg [31:0] x27; + reg [31:0] x28; + reg [31:0] x29; + reg [31:0] x30; + reg [31:0] x31; + + reg [3:0] state; + + reg [31:0] imm; + reg [4:0] dstreg; + reg [31:0] dstvalue; + reg [4:0] divclk; + + reg write; + reg [31:0] writeaddr; + reg [31:0] writedata; + reg [3:0] writemask; + + + assign wWrite = write; + assign bWriteAddr = writeaddr; + assign bWriteData = writedata; + assign bWriteMask = writemask; + + reg [31:0] cur_instr; + always @(posedge wClk) + if (state == `RISCVSTATE_EXEC_INST) + cur_instr <= bReadData; + + wire [31:0] instr = bReadData; + wire [4:0] rs1_no = instr[19:15]; + wire [4:0] rs2_no = instr[24:20]; + wire [4:0] opcode = instr[6:2]; + wire [4:0] rd = instr[11:7]; + wire [2:0] func3 = instr[14:12]; + wire [4:0] rd_r = cur_instr[11:7]; + wire [2:0] func3_r = cur_instr[14:12]; + reg cond; + reg [31:0] rs1; + reg [31:0] rs2; + wire signed [31:0] rs1_s = rs1; + wire signed [31:0] rs2_s = rs2; + wire signed [31:0] imm_s = imm; + wire [31:0] add_result; + wire [31:0] sub_result; + wire [63:0] mul_result; + wire [63:0] muls_result; + wire [71:0] mulsu_result; + wire [31:0] div_result_r, mod_result_r, divs_result_r, mods_result_r; + wire [31:0] div_result, mod_result, divs_result, mods_result; + + adder add(rs1, rs2, add_result); + suber sub(rs1, rs2, sub_result); + mult mul(rs1, rs2, mul_result); + mult_s mul_s(rs1, rs2, muls_result); + mulsu mul_su(rs1, {8'b0, rs2}, mulsu_result); + div div(wClk, rs2, rs1, div_result_r, mod_result_r); + div_s divs(wClk, rs2, rs1, divs_result_r, mods_result_r); + + assign div_result = div_result_r; + assign divs_result = divs_result_r; + assign mod_result = mod_result_r; + assign mods_result = mods_result_r; + + always @(rs1_no or x31 or + x1 or x2 or x3 or x4 or x5 or x6 or x7 or x8 or x9 or x10 or + x11 or x12 or x13 or x14 or x15 or x16 or x17 or x18 or x19 or x20 or + x21 or x22 or x23 or x24 or x25 or x26 or x27 or x28 or x29 or x30 + ) + case (rs1_no) + 5'd0: rs1 = 0; + 5'd1: rs1 = x1; + 5'd2: rs1 = x2; + 5'd3: rs1 = x3; + 5'd4: rs1 = x4; + 5'd5: rs1 = x5; + 5'd6: rs1 = x6; + 5'd7: rs1 = x7; + 5'd8: rs1 = x8; + 5'd9: rs1 = x9; + 5'd10: rs1 = x10; + 5'd11: rs1 = x11; + 5'd12: rs1 = x12; + 5'd13: rs1 = x13; + 5'd14: rs1 = x14; + 5'd15: rs1 = x15; + 5'd16: rs1 = x16; + 5'd17: rs1 = x17; + 5'd18: rs1 = x18; + 5'd19: rs1 = x19; + 5'd20: rs1 = x20; + 5'd21: rs1 = x21; + 5'd22: rs1 = x22; + 5'd23: rs1 = x23; + 5'd24: rs1 = x24; + 5'd25: rs1 = x25; + 5'd26: rs1 = x26; + 5'd27: rs1 = x27; + 5'd28: rs1 = x28; + 5'd29: rs1 = x29; + 5'd30: rs1 = x30; + 5'd31: rs1 = x31; + endcase + + always @(rs2_no or x31 or + x1 or x2 or x3 or x4 or x5 or x6 or x7 or x8 or x9 or x10 or + x11 or x12 or x13 or x14 or x15 or x16 or x17 or x18 or x19 or x20 or + x21 or x22 or x23 or x24 or x25 or x26 or x27 or x28 or x29 or x30 + ) + case (rs2_no) + 5'd0: rs2 = 0; + 5'd1: rs2 = x1; + 5'd2: rs2 = x2; + 5'd3: rs2 = x3; + 5'd4: rs2 = x4; + 5'd5: rs2 = x5; + 5'd6: rs2 = x6; + 5'd7: rs2 = x7; + 5'd8: rs2 = x8; + 5'd9: rs2 = x9; + 5'd10: rs2 = x10; + 5'd11: rs2 = x11; + 5'd12: rs2 = x12; + 5'd13: rs2 = x13; + 5'd14: rs2 = x14; + 5'd15: rs2 = x15; + 5'd16: rs2 = x16; + 5'd17: rs2 = x17; + 5'd18: rs2 = x18; + 5'd19: rs2 = x19; + 5'd20: rs2 = x20; + 5'd21: rs2 = x21; + 5'd22: rs2 = x22; + 5'd23: rs2 = x23; + 5'd24: rs2 = x24; + 5'd25: rs2 = x25; + 5'd26: rs2 = x26; + 5'd27: rs2 = x27; + 5'd28: rs2 = x28; + 5'd29: rs2 = x29; + 5'd30: rs2 = x30; + 5'd31: rs2 = x31; + endcase + + always@(posedge wClk) + if (~nwReset) begin + x1 <= 32'h0000008c; + x2 <= `RAMSIZE * 4 - 16; + end + else + case (dstreg) + 5'd0: ;//0 <= dstvalue; + 5'd1: x1 <= dstvalue; + 5'd2: x2 <= dstvalue; + 5'd3: x3 <= dstvalue; + 5'd4: x4 <= dstvalue; + 5'd5: x5 <= dstvalue; + 5'd6: x6 <= dstvalue; + 5'd7: x7 <= dstvalue; + 5'd8: x8 <= dstvalue; + 5'd9: x9 <= dstvalue; + 5'd10: x10 <= dstvalue; + 5'd11: x11 <= dstvalue; + 5'd12: x12 <= dstvalue; + 5'd13: x13 <= dstvalue; + 5'd14: x14 <= dstvalue; + 5'd15: x15 <= dstvalue; + 5'd16: x16 <= dstvalue; + 5'd17: x17 <= dstvalue; + 5'd18: x18 <= dstvalue; + 5'd19: x19 <= dstvalue; + 5'd20: x20 <= dstvalue; + 5'd21: x21 <= dstvalue; + 5'd22: x22 <= dstvalue; + 5'd23: x23 <= dstvalue; + 5'd24: x24 <= dstvalue; + 5'd25: x25 <= dstvalue; + 5'd26: x26 <= dstvalue; + 5'd27: x27 <= dstvalue; + 5'd28: x28 <= dstvalue; + 5'd29: x29 <= dstvalue; + 5'd30: x30 <= dstvalue; + 5'd31: x31 <= dstvalue; + endcase + + /* cond */ + always @(rs1 or rs2 or rs1_s or rs2_s or func3) + case(func3) + 0:/*beq*/ cond = rs1 == rs2; + 1:/*bne*/ cond = rs1 != rs2; + 4:/*blt*/ cond = rs1_s < rs2_s; + 5:/*bge*/ cond = rs1_s >= rs2_s; + 6:/*bltu*/cond = rs1 < rs2; + 7:/*bgeu*/cond = rs1 >= rs2; + default: cond = 1'b0; + endcase + + always @(instr) + case (instr[6:2]) + 5'h0d: imm = {instr[31:12], 12'b0}; + 5'h05: imm = {instr[31:12], 12'b0}; + 5'h1b: imm = {{12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0}; + 5'h19: imm = {{20{instr[31]}}, instr[31:20]}; + 5'h18: imm = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0}; + 5'h00: imm = {{20{instr[31]}}, instr[31:20]}; + 5'h08: imm = {{20{instr[31]}}, instr[31:25], instr[11:7]}; + 5'h04: imm = {{20{instr[31]}}, instr[31:20]}; + default: imm = 0; + endcase + + + /* state */ + always @(posedge wClk) + if (!nwReset) begin + state <= `RISCVSTATE_STARTUP; + end else begin + case (state) + `RISCVSTATE_STARTUP: state <= `RISCVSTATE_EXEC_INST; + `RISCVSTATE_EXEC_INST: begin + if (opcode == 5'h00) + state <= `RISCVSTATE_WAIT_LD; + else if (opcode == 5'h08) + state <= `RISCVSTATE_WAIT_ST; + else if (opcode == 5'h0c && instr[25] && func3[2] && (rs2 != 0)) begin + state <= `RISCVSTATE_WAIT_DIV; + divclk <= 11; + end + end + `RISCVSTATE_WAIT_LD: state <= `RISCVSTATE_EXEC_INST; + `RISCVSTATE_WAIT_ST: state <= `RISCVSTATE_EXEC_INST; + `RISCVSTATE_WAIT_DIV: begin + if (divclk == 0) + state <= `RISCVSTATE_EXEC_INST; + else + divclk <= divclk - 1; + end + endcase + end + + reg [31:0] newpc; + always @(state or pc or rs1 or imm or cond or opcode) + if (state == `RISCVSTATE_EXEC_INST) begin + case (opcode) + 5'h1b: newpc = pc + imm; + 5'h19: newpc = rs1 + imm; + 5'h18: newpc = cond ? pc + imm : pc + 4; + default: newpc = pc + 4; + endcase + end else begin + newpc = pc; + end + + /* pc */ + always @(posedge wClk) + if (!nwReset) begin + pc <= 32'h00000074; + end else begin + pc <= newpc; + end + + /* read and readaddr */ + always @(state or pc or opcode or imm or rs1 or nwReset) + if (~nwReset) begin + wRead = 0; + bReadAddr = 0; + end else begin + wRead = 1; + bReadAddr = newpc; + if (state == `RISCVSTATE_EXEC_INST) begin + if (opcode == 5'h00) begin /*LOAD*/ + wRead = 1; + bReadAddr = rs1 + imm; + end else if (opcode == 5'h08) begin /*STORE*/ + wRead = 0; + bReadAddr = 0; + end + end + end + + wire [31:0] newwriteaddr = rs1 + imm; + + /* write */ + always @(nwReset or state or opcode or newwriteaddr or rs1 or imm or rs2) + begin + write = 0; + writeaddr = 0; + writemask = 0; + writedata = 0; + if (nwReset && (state == `RISCVSTATE_EXEC_INST) && (opcode == 5'h08)) begin + /* riscv支持地址不对齐访问,但是假定写在一个32位字中 */ + writeaddr = newwriteaddr; + writemask = 4'h0; + writedata = rs2; + write = 1'b1; + case (func3) + 0:/*sb*/ begin + case (newwriteaddr[1:0]) + 0: begin + writemask = 4'he; + writedata = rs2; + end + 1: begin + writemask = 4'hd; + writedata = {rs2[23:0], 8'h0}; + end + 2: begin + writemask = 4'hb; + writedata = {rs2[15:0], 16'h0}; + end + 3: begin + writemask = 4'h7; + writedata = {rs2[7:0], 24'h0}; + end + endcase + end + 1:/*sh*/ begin + case (newwriteaddr[1:0]) + 0: begin + writemask = 4'hc; + writedata = rs2; + end + 1: begin + writemask = 4'h9; + writedata = {rs2[23:0], 8'h0}; + end + 2: begin + writemask = 4'h3; + writedata = {rs2[15:0], 16'h0}; + end + endcase + end + endcase + end + end + + reg [31:0] ldaddr; + + always @(posedge wClk) + if (state == `RISCVSTATE_EXEC_INST) begin + ldaddr <= rs1 + imm; + end + + always @(state or ldaddr or func3_r or rd_r or bReadData or divclk or imm or pc or rs1 or rs2 or instr) begin + dstvalue = 0; + dstreg = 0; + case (state) + `RISCVSTATE_WAIT_LD: begin + dstreg = rd_r; + case (func3_r) + 0: begin + case (ldaddr[1:0]) + 0: dstvalue = {{24{bReadData[7]}}, bReadData[7:0]}; + 1: dstvalue = {{24{bReadData[15]}}, bReadData[15:8]}; + 2: dstvalue = {{24{bReadData[23]}}, bReadData[23:16]}; + 3: dstvalue = {{24{bReadData[31]}}, bReadData[31:24]}; + endcase + end + 1: begin + case (ldaddr[1:0]) + 0: dstvalue = {{16{bReadData[15]}}, bReadData[15:0]}; + 1: dstvalue = {{16{bReadData[23]}}, bReadData[23:8]}; + 2: dstvalue = {{16{bReadData[31]}}, bReadData[31:16]}; + 3: dstvalue = 32'hdeadbeef; + endcase + end + 2: dstvalue = bReadData; + 4: begin + case (ldaddr[1:0]) + 0: dstvalue = {24'b0, bReadData[7:0]}; + 1: dstvalue = {24'b0, bReadData[15:8]}; + 2: dstvalue = {24'b0, bReadData[23:16]}; + 3: dstvalue = {24'b0, bReadData[31:24]}; + endcase + end + 5: begin + case (ldaddr[1:0]) + 0: dstvalue = {16'b0, bReadData[15:0]}; + 1: dstvalue = {16'b0, bReadData[23:8]}; + 2: dstvalue = {16'b0, bReadData[31:16]}; + 3: dstvalue = 32'hdeadbeef; + endcase + end + endcase + end + `RISCVSTATE_WAIT_DIV: if (divclk == 0) begin + case (func3_r[1:0]) + 0: begin //div + dstreg = rd_r; + dstvalue = divs_result; + end + 1: begin //divu + dstreg = rd_r; + dstvalue = div_result; + end + 2: begin//rem + dstreg = rd_r; + dstvalue = mods_result; + end + 3: begin //remu + dstreg = rd_r; + dstvalue = mod_result; + end + endcase + end + `RISCVSTATE_EXEC_INST: begin + dstreg = rd; + case (opcode) + 5'h0d: begin + dstvalue = imm; + end + 5'h05: begin + dstvalue = imm + pc; + end + 5'h1b: begin + dstvalue = pc + 4; + end + 5'h19: begin + dstvalue = pc + 4; + end + 5'h04: begin /* alui */ + case (func3) + 0:/*addi*/ dstvalue = rs1 + imm; + 1:/*slli*/ dstvalue = rs1 << imm[4:0]; + 2:/*slti*/ dstvalue = (rs1_s < imm_s) ? 1 : 0; + 3:/*sltiu*/dstvalue = (rs1 < imm) ? 1 : 0; + 4:/*xori*/ dstvalue = rs1 ^ imm; + 5:/*srli/srai*/ + dstvalue = instr[30] ? (rs1_s >> imm[4:0]) : (rs1 >> imm[4:0]); + 6:/*ori*/ dstvalue = rs1 | imm; + 7:/*andi*/ dstvalue = rs1 & imm; + default: begin dstreg = 0; dstvalue=0; end + endcase + end + 5'h0c: begin /*alu*/ + if (instr[25]) begin /* is MUL/DIV instr*/ + case (func3) + 0: begin //mul + dstvalue = muls_result[31:0]; + end + 1: begin //mulh + dstvalue = muls_result[63:32]; + end + 2: begin //mulhsu + dstvalue = mulsu_result[63:32]; + end + 3: begin //mulhu + dstvalue = mul_result[63:32]; + end + + 4: begin //div + if (rs2 == 0) begin + dstvalue = 32'hffffffff; + end else begin + dstreg = 0; + dstvalue = 0; + end + end + 5: begin //divu + if (rs2 == 0) begin + dstvalue = 32'hffffffff; + end else begin + dstreg = 0; + dstvalue = 0; + end + end + 6: begin//rem + if (rs2 == 0) begin + dstvalue = rs1; + end else begin + dstreg = 0; + dstvalue = 0; + end + end + 7: begin //remu + if (rs2 == 0) begin + dstvalue = rs1; + end else begin + dstreg = 0; + dstvalue = 0; + end + end + endcase + end else begin + case (func3) + 0: begin + if (instr[30]) + dstvalue = sub_result; + else + dstvalue = add_result; + end + 1: begin //sll + dstvalue = rs1 << rs2[4:0]; + end + 2: begin //slt + dstvalue = (rs1_s < rs2_s) ? 1 : 0; + end + 3: begin //sltu + dstvalue = (rs1 < rs2) ? 1 : 0; + end + 4: begin //xor + dstvalue = rs1 ^ rs2; + end + 5: begin //srl/sra + if (instr[30]) + dstvalue = rs1 >> rs2[4:0]; + else + dstvalue = rs1_s >> rs2[4:0]; + end + 6: begin //or + dstvalue = rs1 | rs2; + end + 7: begin //and + dstvalue = rs1 & rs2; + end + endcase + end + end + default: begin + dstreg = 0; + dstvalue = 0; + end + endcase + end + endcase + end + +endmodule \ No newline at end of file diff --git a/examples/hdl4se_riscv/verilog/riscv_sim_dump_v4.v b/examples/hdl4se_riscv/verilog/riscv_sim_dump_v4.v index 606ba9fc28ae3b59396972242ef50c47a33781aa..5876e99e208a1f0a4dacd11afbbb0373faa4371f 100644 --- a/examples/hdl4se_riscv/verilog/riscv_sim_dump_v4.v +++ b/examples/hdl4se_riscv/verilog/riscv_sim_dump_v4.v @@ -14,18 +14,25 @@ module riscv_core output [32'h3:32'h0] bWriteMask, output reg wRead, output reg [32'h1f:32'h0] bReadAddr, - input [32'h1f:32'h0] bReadData + input [32'h1f:32'h0] bReadData, + output reg [32'h4:32'h0] regno, + output reg [32'h3:32'h0] regena, + output reg [32'h1f:32'h0] regwrdata, + output reg regwren, + input [32'h1f:32'h0] regrddata, + output reg [32'h4:32'h0] regno2, + output reg [32'h3:32'h0] regena2, + output reg [32'h1f:32'h0] regwrdata2, + output reg regwren2, + input [32'h1f:32'h0] regrddata2 ) ; - wire [32'h1f:32'h0] instr; - wire [32'h4:32'h0] rs1_no; - wire [32'h4:32'h0] rs2_no; wire [32'h4:32'h0] opcode; wire [32'h4:32'h0] rd; wire [32'h2:32'h0] func3; - wire [32'h4:32'h0] rd_r; - wire [32'h2:32'h0] func3_r; + wire [32'h1f:32'h0] rs1; + wire [32'h1f:32'h0] rs2; wire [32'h1f:32'h0] rs1_s; wire [32'h1f:32'h0] rs2_s; wire [32'h1f:32'h0] imm_s; @@ -51,14 +58,11 @@ module riscv_core assign divs_result = divs_result_r; assign mod_result = mod_result_r; assign mods_result = mods_result_r; - assign instr = bReadData; - assign rs1_no = instr [19:15] ; - assign rs2_no = instr [24:20] ; assign opcode = instr [6:2] ; assign rd = instr [11:7] ; assign func3 = instr [14:12] ; - assign rd_r = cur_instr [11:7] ; - assign func3_r = cur_instr [14:12] ; + assign rs1 = regrddata; + assign rs2 = regrddata2; assign rs1_s = rs1; assign rs2_s = rs2; assign imm_s = imm; @@ -70,123 +74,6 @@ module riscv_core mulsu mul_su( rs1, {0,rs2}, mulsu_result ); div div( wClk, rs2, rs1, div_result_r, mod_result_r ); div_s divs( wClk, rs2, rs1, divs_result_r, mods_result_r ); - always @(posedge wClk) - if ((state==1)) - cur_instr <= bReadData; - always @* - case (rs1_no) - 5'd0: rs1 = 0; - 5'd1: rs1 = x1; - 5'd2: rs1 = x2; - 5'd3: rs1 = x3; - 5'd4: rs1 = x4; - 5'd5: rs1 = x5; - 5'd6: rs1 = x6; - 5'd7: rs1 = x7; - 5'd8: rs1 = x8; - 5'd9: rs1 = x9; - 5'd10: rs1 = x10; - 5'd11: rs1 = x11; - 5'd12: rs1 = x12; - 5'd13: rs1 = x13; - 5'd14: rs1 = x14; - 5'd15: rs1 = x15; - 5'd16: rs1 = x16; - 5'd17: rs1 = x17; - 5'd18: rs1 = x18; - 5'd19: rs1 = x19; - 5'd20: rs1 = x20; - 5'd21: rs1 = x21; - 5'd22: rs1 = x22; - 5'd23: rs1 = x23; - 5'd24: rs1 = x24; - 5'd25: rs1 = x25; - 5'd26: rs1 = x26; - 5'd27: rs1 = x27; - 5'd28: rs1 = x28; - 5'd29: rs1 = x29; - 5'd30: rs1 = x30; - 5'd31: rs1 = x31; - endcase - - always @* - case (rs2_no) - 5'd0: rs2 = 0; - 5'd1: rs2 = x1; - 5'd2: rs2 = x2; - 5'd3: rs2 = x3; - 5'd4: rs2 = x4; - 5'd5: rs2 = x5; - 5'd6: rs2 = x6; - 5'd7: rs2 = x7; - 5'd8: rs2 = x8; - 5'd9: rs2 = x9; - 5'd10: rs2 = x10; - 5'd11: rs2 = x11; - 5'd12: rs2 = x12; - 5'd13: rs2 = x13; - 5'd14: rs2 = x14; - 5'd15: rs2 = x15; - 5'd16: rs2 = x16; - 5'd17: rs2 = x17; - 5'd18: rs2 = x18; - 5'd19: rs2 = x19; - 5'd20: rs2 = x20; - 5'd21: rs2 = x21; - 5'd22: rs2 = x22; - 5'd23: rs2 = x23; - 5'd24: rs2 = x24; - 5'd25: rs2 = x25; - 5'd26: rs2 = x26; - 5'd27: rs2 = x27; - 5'd28: rs2 = x28; - 5'd29: rs2 = x29; - 5'd30: rs2 = x30; - 5'd31: rs2 = x31; - endcase - - always @(posedge wClk) - if ((~(nwReset))) - begin - x1 <= 32'h0000008c; - x2 <= ((4096*4)-16); - end - else - case (dstreg) - 5'd0: - 5'd1: x1 <= dstvalue; - 5'd2: x2 <= dstvalue; - 5'd3: x3 <= dstvalue; - 5'd4: x4 <= dstvalue; - 5'd5: x5 <= dstvalue; - 5'd6: x6 <= dstvalue; - 5'd7: x7 <= dstvalue; - 5'd8: x8 <= dstvalue; - 5'd9: x9 <= dstvalue; - 5'd10: x10 <= dstvalue; - 5'd11: x11 <= dstvalue; - 5'd12: x12 <= dstvalue; - 5'd13: x13 <= dstvalue; - 5'd14: x14 <= dstvalue; - 5'd15: x15 <= dstvalue; - 5'd16: x16 <= dstvalue; - 5'd17: x17 <= dstvalue; - 5'd18: x18 <= dstvalue; - 5'd19: x19 <= dstvalue; - 5'd20: x20 <= dstvalue; - 5'd21: x21 <= dstvalue; - 5'd22: x22 <= dstvalue; - 5'd23: x23 <= dstvalue; - 5'd24: x24 <= dstvalue; - 5'd25: x25 <= dstvalue; - 5'd26: x26 <= dstvalue; - 5'd27: x27 <= dstvalue; - 5'd28: x28 <= dstvalue; - 5'd29: x29 <= dstvalue; - 5'd30: x30 <= dstvalue; - 5'd31: x31 <= dstvalue; - endcase - always @* case (func3) 0: cond = (rs1==rs2); @@ -198,19 +85,191 @@ module riscv_core default: cond = 1'b0; endcase - always @* - case (instr [6:2] ) - 5'h0d: imm = {instr [31:12] ,12'b0}; - 5'h05: imm = {instr [31:12] ,12'b0}; - 5'h1b: imm = {{12{instr [31] }{,instr [19:12] ,instr [20] ,instr [30:21] ,1'b0}; - 5'h19: imm = {{20{instr [31] }{,instr [31:20] }; - 5'h18: imm = {{20{instr [31] }{,instr [7] ,instr [30:25] ,instr [11:8] ,1'b0}; - 5'h00: imm = {{20{instr [31] }{,instr [31:20] }; - 5'h08: imm = {{20{instr [31] }{,instr [31:25] ,instr [11:7] }; - 5'h04: imm = {{20{instr [31] }{,instr [31:20] }; - default: imm = 0; - endcase - + always @(posedge wClk) + if ((state==6)) + begin + lastaddr <= ldaddr; + if (((func3==1)&&(ldaddr [1:0] ==3))) + begin + lastv <= {24'b0,bReadData [31:24] }; + end + else + if (((func3==2)&&(ldaddr [1:0] !=0))) + begin + if ((ldaddr [1:0] ==1)) + lastv <= {8'b0,bReadData [31:8] }; + else + if ((ldaddr [1:0] ==2)) + lastv <= {16'b0,bReadData [31:16] }; + else + lastv <= {24'b0,bReadData [31:24] }; + end + else + if (((func3==5)&&(ldaddr [1:0] ==3))) + begin + lastv <= {24'b0,bReadData [31:24] }; + end + end + else + if ((state==4)) + begin + lastaddr <= (rs1+imm); + lastv <= rs2; + end + always @(posedge wClk) + if ((!(nwReset))) + begin + pc <= 32'h00000074; + end + else + begin + if ((state==4)) + begin + case (opcode) + 5'h1b: pc <= (pc+imm); + 5'h19: pc <= (rs1+imm); + 5'h18: pc <= ((cond)?((pc+imm)):((pc+4))); + default: pc <= (pc+4); + endcase + + end + end + always @(posedge wClk) + if ((state==3)) + instr <= bReadData; + always @(posedge wClk) + if ((state==4)) + if ((opcode==5'h00)) + readreg <= rd; + always @(posedge wClk) + if ((!(nwReset))) + begin + write <= 0; + end + else + if ((state==4)) + begin + write <= 0; + if ((opcode==5'h08)) + begin + writeaddr <= newwriteaddr; + writemask <= 4'h0; + writedata <= rs2; + write <= 1'b1; + case (func3) + 0: begin + case (newwriteaddr [1:0] ) + 0: begin + writemask <= 4'he; + writedata <= rs2; + end + 1: begin + writemask <= 4'hd; + writedata <= {rs2 [23:0] ,8'h0}; + end + 2: begin + writemask <= 4'hb; + writedata <= {rs2 [15:0] ,16'h0}; + end + 3: begin + writemask <= 4'h7; + writedata <= {rs2 [7:0] ,24'h0}; + end + endcase + + end + 1: begin + case (newwriteaddr [1:0] ) + 0: begin + writemask <= 4'hc; + writedata <= rs2; + end + 1: begin + writemask <= 4'h9; + writedata <= {rs2 [23:0] ,8'h0}; + end + 2: begin + writemask <= 4'h3; + writedata <= {rs2 [15:0] ,16'h0}; + end + 3: begin + writemask <= 4'h7; + writedata <= {rs2 [7:0] ,24'h0}; + end + endcase + + end + 2: begin + case (newwriteaddr [1:0] ) + 0: begin + writemask <= 4'h0; + writedata <= rs2; + end + 1: begin + writemask <= 4'h1; + writedata <= {rs2 [23:0] ,8'h0}; + end + 2: begin + writemask <= 4'h3; + writedata <= {rs2 [15:0] ,16'h0}; + end + 3: begin + writemask <= 4'h7; + writedata <= {rs2 [7:0] ,24'h0}; + end + endcase + + end + endcase + + end + end + else + if ((state==8)) + begin + write <= 0; + writeaddr <= (lastaddr+4); + if ((opcode==5'h08)) + begin + case (func3) + 1: begin + case (lastaddr [1:0] ) + 3: begin + writemask <= 4'he; + writedata <= {24'b0,lastv [31:24] }; + write <= 1; + end + endcase + + end + 2: begin + case (lastaddr [1:0] ) + 1: begin + writemask <= 4'he; + writedata <= {24'b0,lastv [31:24] }; + write <= 1; + end + 2: begin + writemask <= 4'hc; + writedata <= {16'b0,lastv [31:16] }; + write <= 1; + end + 3: begin + writemask <= 4'h8; + writedata <= {8'b0,lastv [31:8] }; + write <= 1; + end + endcase + + end + endcase + + end + end + else + begin + write <= 0; + end always @(posedge wClk) if ((!(nwReset))) begin @@ -220,237 +279,278 @@ module riscv_core begin case (state) 0: state <= 1; - 1: begin + 1: state <= 2; + 2: state <= 3; + 3: state <= 4; + 5: state <= 2; + 4: begin if ((opcode==5'h00)) - state <= 2; + state <= 6; else if ((opcode==5'h08)) - state <= 3; + state <= 8; else if (((((opcode==5'h0c)&&instr [25] )&&func3 [2] )&&(rs2!=0))) begin - state <= 4; + state <= 10; divclk <= 11; end + else + state <= 5; end - 2: state <= 1; - 3: state <= 1; - 4: begin + 6: begin + if (((func3==1)&&(ldaddr [1:0] ==3))) + begin + state <= 7; + end + else + if (((func3==2)&&(ldaddr [1:0] !=0))) + begin + state <= 7; + end + else + if (((func3==5)&&(ldaddr [1:0] ==3))) + begin + state <= 7; + end + else + begin + state <= 5; + end + end + 7: state <= 5; + 8: begin + state <= 2; + if ((opcode==5'h08)) + begin + if (((func3==1)&&((lastaddr&3)==3))) + begin + state <= 9; + end + else + if (((func3==2)&&((lastaddr&3)!=0))) + begin + state <= 9; + end + end + end + 9: state <= 2; + 10: begin if ((divclk==0)) - state <= 1; + state <= 5; else divclk <= (divclk-1); end endcase end - always @* - if ((state==1)) + always @(posedge wClk) + if ((state==3)) begin - case (opcode) - 5'h1b: newpc = (pc+imm); - 5'h19: newpc = (rs1+imm); - 5'h18: newpc = ((cond)?((pc+imm)):((pc+4))); - default: newpc = (pc+4); + case (bReadData [6:2] ) + 5'h0d: imm <= {bReadData [31:12] ,12'b0}; + 5'h05: imm <= {bReadData [31:12] ,12'b0}; + 5'h1b: imm <= {{12{bReadData [31] }{,bReadData [19:12] ,bReadData [20] ,bReadData [30:21] ,1'b0}; + 5'h19: imm <= {{20{bReadData [31] }{,bReadData [31:20] }; + 5'h18: imm <= {{20{bReadData [31] }{,bReadData [7] ,bReadData [30:25] ,bReadData [11:8] ,1'b0}; + 5'h00: imm <= {{20{bReadData [31] }{,bReadData [31:20] }; + 5'h08: imm <= {{20{bReadData [31] }{,bReadData [31:25] ,bReadData [11:7] }; + 5'h04: imm <= {{20{bReadData [31] }{,bReadData [31:20] }; endcase end - else - begin - newpc = pc; + always @* + case (state) + 3: begin + regno = bReadData [19:15] ; + regwren = 0; + regena = 0; + regwrdata = 0; + regno2 = bReadData [24:20] ; + regwren2 = 0; + regena2 = 0; + regwrdata2 = 0; end - always @(posedge wClk) - if ((!(nwReset))) - begin - pc <= 32'h00000074; + 5: begin + regwren = (((dstreg!=0))?(1):(0)); + regno = dstreg; + regena = 4'hf; + regwrdata = dstvalue; + regwren2 = (((dstreg!=0))?(1):(0)); + regno2 = dstreg; + regena2 = 4'hf; + regwrdata2 = dstvalue; end - else - begin - pc <= newpc; + 0: begin + regwren = 1; + regno = 1; + regena = 4'hf; + regwrdata = 32'h8c; + regwren2 = 1; + regno2 = 1; + regena2 = 4'hf; + regwrdata2 = 32'h8c; end - always @* - if ((~(nwReset))) + 1: begin + regwren = 1; + regno = 2; + regena = 4'hf; + regwrdata = ((4096*4)-16); + regwren2 = 1; + regno2 = 2; + regena2 = 4'hf; + regwrdata2 = ((4096*4)-16); + end + default: begin + regwren = 0; + regno = 0; + regena = 0; + regwrdata = 0; + regwren2 = 0; + regno2 = 0; + regena2 = 0; + regwrdata2 = 0; + end + endcase + + always @(posedge wClk) + if ((state==2)) begin - wRead = 0; - bReadAddr = 0; + ldaddr <= pc; end else - begin - wRead = 1; - bReadAddr = newpc; - if ((state==1)) + if ((state==4)) begin if ((opcode==5'h00)) begin - wRead = 1; - bReadAddr = (rs1+imm); + ldaddr <= (rs1+imm); end - else - if ((opcode==5'h08)) - begin - wRead = 0; - bReadAddr = 0; - end end - end - always @* - begin - write = 0; - writeaddr = 0; - writemask = 0; - writedata = 0; - if (((nwReset&&(state==1))&&(opcode==5'h08))) - begin - writeaddr = newwriteaddr; - writemask = 4'h0; - writedata = rs2; - write = 1'b1; - case (func3) - 0: begin - case (newwriteaddr [1:0] ) - 0: begin - writemask = 4'he; - writedata = rs2; - end - 1: begin - writemask = 4'hd; - writedata = {rs2 [23:0] ,8'h0}; - end - 2: begin - writemask = 4'hb; - writedata = {rs2 [15:0] ,16'h0}; - end - 3: begin - writemask = 4'h7; - writedata = {rs2 [7:0] ,24'h0}; - end - endcase - - end - 1: begin - case (newwriteaddr [1:0] ) - 0: begin - writemask = 4'hc; - writedata = rs2; - end - 1: begin - writemask = 4'h9; - writedata = {rs2 [23:0] ,8'h0}; - end - 2: begin - writemask = 4'h3; - writedata = {rs2 [15:0] ,16'h0}; - end - endcase - - end - endcase - - end - end always @(posedge wClk) - if ((state==1)) - begin - ldaddr <= (rs1+imm); - end - always @* - begin - dstvalue = 0; - dstreg = 0; - case (state) - 2: begin - dstreg = rd_r; - case (func3_r) + case (state) + 6: begin + dstreg <= readreg; + case (func3) 0: begin case (ldaddr [1:0] ) - 0: dstvalue = {{24{bReadData [7] }{,bReadData [7:0] }; - 1: dstvalue = {{24{bReadData [15] }{,bReadData [15:8] }; - 2: dstvalue = {{24{bReadData [23] }{,bReadData [23:16] }; - 3: dstvalue = {{24{bReadData [31] }{,bReadData [31:24] }; + 0: dstvalue <= {{24{bReadData [7] }{,bReadData [7:0] }; + 1: dstvalue <= {{24{bReadData [15] }{,bReadData [15:8] }; + 2: dstvalue <= {{24{bReadData [23] }{,bReadData [23:16] }; + 3: dstvalue <= {{24{bReadData [31] }{,bReadData [31:24] }; endcase end 1: begin case (ldaddr [1:0] ) - 0: dstvalue = {{16{bReadData [15] }{,bReadData [15:0] }; - 1: dstvalue = {{16{bReadData [23] }{,bReadData [23:8] }; - 2: dstvalue = {{16{bReadData [31] }{,bReadData [31:16] }; - 3: dstvalue = 32'hdeadbeef; + 0: dstvalue <= {{16{bReadData [15] }{,bReadData [15:0] }; + 1: dstvalue <= {{16{bReadData [23] }{,bReadData [23:8] }; + 2: dstvalue <= {{16{bReadData [31] }{,bReadData [31:16] }; + 3: dstvalue <= 32'hdeadbeef; endcase end - 2: dstvalue = bReadData; + 2: dstvalue <= bReadData; 4: begin case (ldaddr [1:0] ) - 0: dstvalue = {24'b0,bReadData [7:0] }; - 1: dstvalue = {24'b0,bReadData [15:8] }; - 2: dstvalue = {24'b0,bReadData [23:16] }; - 3: dstvalue = {24'b0,bReadData [31:24] }; + 0: dstvalue <= {24'b0,bReadData [7:0] }; + 1: dstvalue <= {24'b0,bReadData [15:8] }; + 2: dstvalue <= {24'b0,bReadData [23:16] }; + 3: dstvalue <= {24'b0,bReadData [31:24] }; endcase end 5: begin case (ldaddr [1:0] ) - 0: dstvalue = {16'b0,bReadData [15:0] }; - 1: dstvalue = {16'b0,bReadData [23:8] }; - 2: dstvalue = {16'b0,bReadData [31:16] }; - 3: dstvalue = 32'hdeadbeef; + 0: dstvalue <= {16'b0,bReadData [15:0] }; + 1: dstvalue <= {16'b0,bReadData [23:8] }; + 2: dstvalue <= {16'b0,bReadData [31:16] }; + 3: dstvalue <= 32'hdeadbeef; endcase end endcase end - 4: if ((divclk==0)) + 7: begin + dstreg <= rd; + if (((func3==1)&&(ldaddr [1:0] ==3))) begin - case (func3_r [1:0] ) + dstvalue <= {{16{bReadData [7] }{,bReadData [7:0] ,lastv [7:0] }; + end + else + if (((func3==2)&&(ldaddr [1:0] !=0))) + begin + if ((ldaddr [1:0] ==1)) + dstvalue <= {bReadData [7:0] ,lastv [23:0] }; + else + if ((ldaddr [1:0] ==2)) + dstvalue <= {bReadData [15:0] ,lastv [15:0] }; + else + if ((ldaddr [1:0] ==3)) + dstvalue <= {bReadData [23:0] ,lastv [7:0] }; + end + else + if (((func3==5)&&(ldaddr [1:0] ==3))) + begin + dstvalue <= {16'b0,bReadData [7:0] ,lastv [7:0] }; + end + else + begin + dstreg <= 0; + dstvalue <= 0; + end + end + 10: if ((divclk==0)) + begin + dstreg <= 0; + case (func3 [1:0] ) 0: begin - dstreg = rd_r; - dstvalue = divs_result; + dstreg <= rd; + dstvalue <= divs_result; end 1: begin - dstreg = rd_r; - dstvalue = div_result; + dstreg <= rd; + dstvalue <= div_result; end 2: begin - dstreg = rd_r; - dstvalue = mods_result; + dstreg <= rd; + dstvalue <= mods_result; end 3: begin - dstreg = rd_r; - dstvalue = mod_result; + dstreg <= rd; + dstvalue <= mod_result; end endcase end - 1: begin - dstreg = rd; + 4: begin + dstreg <= rd; case (opcode) 5'h0d: begin - dstvalue = imm; + dstvalue <= imm; end 5'h05: begin - dstvalue = (imm+pc); + dstvalue <= (imm+pc); end 5'h1b: begin - dstvalue = (pc+4); + dstvalue <= (pc+4); end 5'h19: begin - dstvalue = (pc+4); + dstvalue <= (pc+4); end 5'h04: begin case (func3) - 0: dstvalue = (rs1+imm); - 1: dstvalue = (rs1<>imm [4:0] )):((rs1>>imm [4:0] ))); - 6: dstvalue = (rs1|imm); - 7: dstvalue = (rs1&imm); + 0: dstvalue <= (rs1+imm); + 1: dstvalue <= (rs1<>imm [4:0] )):((rs1>>imm [4:0] ))); + 6: dstvalue <= (rs1|imm); + 7: dstvalue <= (rs1&imm); default: begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end endcase @@ -460,59 +560,59 @@ module riscv_core begin case (func3) 0: begin - dstvalue = muls_result [31:0] ; + dstvalue <= muls_result [31:0] ; end 1: begin - dstvalue = muls_result [63:32] ; + dstvalue <= muls_result [63:32] ; end 2: begin - dstvalue = mulsu_result [63:32] ; + dstvalue <= mulsu_result [63:32] ; end 3: begin - dstvalue = mul_result [63:32] ; + dstvalue <= mul_result [63:32] ; end 4: begin if ((rs2==0)) begin - dstvalue = 32'hffffffff; + dstvalue <= 32'hffffffff; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end 5: begin if ((rs2==0)) begin - dstvalue = 32'hffffffff; + dstvalue <= 32'hffffffff; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end 6: begin if ((rs2==0)) begin - dstvalue = rs1; + dstvalue <= rs1; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end 7: begin if ((rs2==0)) begin - dstvalue = rs1; + dstvalue <= rs1; end else begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end end endcase @@ -523,47 +623,91 @@ module riscv_core case (func3) 0: begin if (instr [30] ) - dstvalue = sub_result; + dstvalue <= sub_result; else - dstvalue = add_result; + dstvalue <= add_result; end 1: begin - dstvalue = (rs1<>rs2 [4:0] ); + dstvalue <= (rs1>>rs2 [4:0] ); else - dstvalue = (rs1_s>>rs2 [4:0] ); + dstvalue <= (rs1_s>>rs2 [4:0] ); end 6: begin - dstvalue = (rs1|rs2); + dstvalue <= (rs1|rs2); end 7: begin - dstvalue = (rs1&rs2); + dstvalue <= (rs1&rs2); end endcase end end default: begin - dstreg = 0; - dstvalue = 0; + dstreg <= 0; + dstvalue <= 0; end endcase end endcase + always @* + begin + wRead = 0; + bReadAddr = 0; + if ((state==2)) + begin + wRead = 1; + bReadAddr = pc; + end + else + if ((state==4)) + begin + if ((opcode==5'h00)) + begin + bReadAddr = (rs1+imm); + wRead = 1; + end + end + else + if ((state==6)) + begin + if (((func3==1)&&((ldaddr&3)==3))) + begin + wRead = 1; + bReadAddr = (ldaddr+4); + end + else + if (((func3==2)&&((ldaddr&3)!=0))) + begin + wRead = 1; + bReadAddr = (ldaddr+4); + end + else + if (((func3==5)&&((ldaddr&3)==3))) + begin + wRead = 1; + bReadAddr = (ldaddr+4); + end + else + begin + wRead = 0; + bReadAddr = 0; + end + end end endmodule @@ -612,6 +756,26 @@ endmodule +(* + HDL4SE = "LCOM", + CLSID = "2E577C6B-2FF1-425E-90B3-947EB523B863", + softmodule = "hdl4se" +*) +module regfile + ( + input [32'h4:32'h0] address, + input [32'h3:32'h0] byteena, + input clock, + input [32'h1f:32'h0] data, + input wren, + output [32'h1f:32'h0] q + ) + ; + +endmodule + + + (* HDL4SE = "LCOM", CLSID = "76FBFD4B-FEAD-45fd-AA27-AFC58AC241C2", @@ -653,16 +817,32 @@ module top wire wRead_out; wire [32'h1f:32'h0] bReadAddr_out; wire [32'h1d:32'h0] ramaddr; + wire [32'h4:32'h0] regno; + wire [32'h3:32'h0] regena; + wire [32'h1f:32'h0] regwrdata; + wire regwren; + wire [32'h1f:32'h0] regrddata; + wire [32'h4:32'h0] regno2; + wire [32'h3:32'h0] regena2; + wire [32'h1f:32'h0] regwrdata2; + wire regwren2; + wire [32'h1f:32'h0] regrddata2; assign bReadData = ((((bReadAddr_out&32'hffffff00)==32'hf0000000))?(bReadDataKey):(((((bReadAddr_out&32'hff000000)==32'h0))?(bReadDataRam):(32'hffffffff)))); assign ramaddr = ((wWrite)?(bWriteAddr [31:2] ):(bReadAddr [31:2] )); hdl4se_reg #( 32'h1 ) readcmd( wClk, wRead, wRead_out ); hdl4se_reg #( 32'h20 ) readaddr( wClk, bReadAddr, bReadAddr_out ); + regfile regs( regno, regena, wClk, regwrdata, regwren, regrddata + ); + regfile regs2( regno2, regena2, wClk, regwrdata2, regwren2, regrddata2 + ); ram8kb ram( ramaddr, (~(bWriteMask)), wClk, bWriteData, ((((bWriteAddr&32'hff000000)==32'h0))?(wWrite):(0)), bReadDataRam ); digitled led( wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask , wRead, bReadAddr, bReadDataKey ); riscv_core core( wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask - , wRead, bReadAddr, bReadData ); + , wRead, bReadAddr, bReadData, regno, regena + , regwrdata, regwren, regrddata, regno2, regena2 + , regwrdata2, regwren2, regrddata2 ); endmodule module adder not found when declare instance add module suber not found when declare instance sub diff --git a/examples/hdl4se_riscv/verilog/riscv_sim_v4.v b/examples/hdl4se_riscv/verilog/riscv_sim_v4.v index 629465bf1d679df38600b3050527364d9a973d06..b06edf01f889f21bce30d3da1175899031ae5cb4 100644 --- a/examples/hdl4se_riscv/verilog/riscv_sim_v4.v +++ b/examples/hdl4se_riscv/verilog/riscv_sim_v4.v @@ -63,6 +63,21 @@ module ram8kb ( output [31:0] q); endmodule +(* + HDL4SE="LCOM", + CLSID="2E577C6B-2FF1-425E-90B3-947EB523B863", + softmodule="hdl4se" +*) +module regfile ( + input [4:0] address, + input [3:0] byteena, + input clock, + input [31:0] data, + input wren, + output [31:0] q); +endmodule + + (* HDL4SE="LCOM", CLSID="76FBFD4B-FEAD-45fd-AA27-AFC58AC241C2", @@ -98,8 +113,24 @@ module top(input wClk, nwReset); wire [29:0] ramaddr; assign ramaddr = wWrite?bWriteAddr[31:2]:bReadAddr[31:2]; + wire [4:0] regno; + wire [3:0] regena; + wire [31:0] regwrdata; + wire regwren; + wire [31:0] regrddata; + wire [4:0] regno2; + wire [3:0] regena2; + wire [31:0] regwrdata2; + wire regwren2; + wire [31:0] regrddata2; + + regfile regs(regno, regena, wClk, regwrdata, regwren, regrddata); + regfile regs2(regno2, regena2, wClk, regwrdata2, regwren2, regrddata2); ram8kb ram(ramaddr, ~bWriteMask, wClk, bWriteData, ((bWriteAddr & 32'hff000000) == 0)?wWrite:1'b0, bReadDataRam); digitled led(wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask, wRead, bReadAddr, bReadDataKey); - riscv_core core(wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask, wRead, bReadAddr, bReadData); + riscv_core core(wClk, nwReset, wWrite, bWriteAddr, bWriteData, bWriteMask, wRead, bReadAddr, bReadData, + regno, regena, regwrdata, regwren, regrddata, + regno2, regena2, regwrdata2, regwren2, regrddata2 + ); endmodule