riscv_core_v4.v 32.7 KB
Newer Older
饶先宏's avatar
饶先宏 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

/*
** HDL4SE: 软件Verilog综合仿真平台
** Copyright (C) 2021-2021, raoxianhong<raoxianhong@163.net>
** LCOM: 轻量级组件对象模型
** Copyright (C) 2021-2021, raoxianhong<raoxianhong@163.net>
** 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.
*/
饶先宏's avatar
饶先宏 已提交
32
/* riscv_core_v4.v */
饶先宏's avatar
饶先宏 已提交
33

饶先宏's avatar
饶先宏 已提交
34 35 36 37 38
`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
39 40 41 42 43
`define RISCVSTATE_WAIT_LD      5
`define RISCVSTATE_WAIT_LD2     6
`define RISCVSTATE_WAIT_ST      7
`define RISCVSTATE_WAIT_ST2     8
`define RISCVSTATE_WAIT_DIV     9
饶先宏's avatar
饶先宏 已提交
44
`define RISCVSTATE_WAIT_MUL     10
饶先宏's avatar
饶先宏 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

`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,
饶先宏's avatar
饶先宏 已提交
61 62 63 64 65 66 67 68 69 70 71
    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
饶先宏's avatar
饶先宏 已提交
72 73
    );

饶先宏's avatar
饶先宏 已提交
74 75 76 77 78 79 80 81 82 83 84 85
    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;
饶先宏's avatar
饶先宏 已提交
86
    reg [4:0]   divclk;
饶先宏's avatar
饶先宏 已提交
87 88
    reg [31:0]  lastv;
    reg [31:0]  lastaddr;
饶先宏's avatar
饶先宏 已提交
89

饶先宏's avatar
饶先宏 已提交
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
    /* CSR register */
    reg [31:0] misa;      /*0301*/
    reg [31:0] ucycle;    /*0c00*/
    reg [31:0] utime;     /*0c01*/
    reg [31:0] uinstret;  /*0c02*/
    reg [31:0] ucycleh;   /*0c80*/
    reg [31:0] utimeh;    /*0c81*/
    reg [31:0] uinstreth; /*0c82*/
    reg [31:0] mcycle;    /*0b00*/
    reg [31:0] minstret;  /*0b02*/
    reg [31:0] mcycleh;   /*0b80*/
    reg [31:0] minstreth;  /*0b82*/
    reg [31:0] csr_r;

    always @(posedge wClk)
    if (state == `RISCVSTATE_READ_REGS)
    case (bReadData[31:20])
    12'h301: csr_r <= misa;
    12'hc00: csr_r <= ucycle;
    12'hc01: csr_r <= utime;
    12'hc02: csr_r <= uinstret;
    12'hc80: csr_r <= ucycleh;
    12'hc81: csr_r <= utimeh;
    12'hc82: csr_r <= uinstreth;
    12'hb00: csr_r <= mcycle;
    12'hb02: csr_r <= minstret;
    12'hb80: csr_r <= mcycleh;
    12'hb82: csr_r <= minstreth;
    default: csr_r <= 0;
    endcase

饶先宏's avatar
饶先宏 已提交
121 122 123 124 125
    assign wWrite = write;
    assign bWriteAddr = writeaddr;
    assign bWriteData = writedata;
    assign bWriteMask = writemask;

饶先宏's avatar
饶先宏 已提交
126 127 128
    wire [4:0]  opcode = instr[6:2];
    wire [4:0]  rd = instr[11:7];
    wire [2:0]  func3 = instr[14:12];
饶先宏's avatar
饶先宏 已提交
129
    reg cond;
饶先宏's avatar
饶先宏 已提交
130 131
    wire [31:0] rs1 = regrddata;
    wire [31:0] rs2 = regrddata2;
饶先宏's avatar
饶先宏 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144
    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);
饶先宏's avatar
饶先宏 已提交
145 146 147 148

`define USE3MUL

`ifdef USE3MUL
饶先宏's avatar
饶先宏 已提交
149 150 151
    mult mul(rs1, rs2, mul_result);
    mult_s mul_s(rs1, rs2, muls_result);
    mulsu mul_su(rs1, {8'b0, rs2}, mulsu_result);
饶先宏's avatar
饶先宏 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
`else
    wire signed [63:0] mul_result_sign = mul_result;
    reg [31:0] mul_rs1, mul_rs2;
    wire [31:0] rs1_abs = rs1[31] ? (~rs1 + 1) : rs1;
    wire [31:0] rs2_abs = rs2[31] ? (~rs2 + 1) : rs2;

    mult mul(mul_rs1, mul_rs2, mul_result);

    wire [1:0] mul_unsign_op = func3[1:0];
    reg [1:0] mul_unsign;
    reg mul_s;

    assign muls_result = mul_s?(-mul_result_sign):mul_result_sign;
    assign mulsu_result = mul_s?(-mul_result_sign):mul_result_sign;

    always @(mul_unsign_op or rs1 or rs2 or rs1_abs or rs2_abs)
    case (mul_unsign_op)
    0:  begin /* mul */
        mul_rs1 = rs1_abs;
        mul_rs2 = rs2_abs;
    end
    1:  begin /* mulh */
        mul_rs1 = rs1_abs;
        mul_rs2 = rs2_abs;
    end
    2:  begin /* mulhsu */
        mul_rs1 = rs1_abs;
        mul_rs2 = rs2;
    end
    3:  begin /* mul */
        mul_rs1 = rs1;
        mul_rs2 = rs2;
    end
    endcase 

    always @(posedge wClk)
    if (state == `RISCVSTATE_EXEC_INST) begin
        mul_unsign <= mul_unsign_op;
        case (mul_unsign_op)
        0:  /* mul */
            mul_s <= rs1[31] ^ rs2[31];
        1:  /* mulh */
            mul_s <= rs1[31] ^ rs2[31];
        2: /* mulhsu */
            mul_s <= rs1[31];
        3: /* mulhu */
            mul_s <= 1'b0;
        endcase 
    end

`endif

    /*
    两个除法器:
    Total logic elements	8,079 / 114,480 ( 7 % )
    Total combinational functions	7,107 / 114,480 ( 6 % )
    Dedicated logic registers	4,309 / 114,480 ( 4 % )
    Total registers	4309
    Embedded Multiplier 9-bit elements	0 / 532 ( 0 % )

    一个除法器:
    Total logic elements	6,264 / 114,480 ( 5 % )
    Total combinational functions	5,607 / 114,480 ( 5 % )
    Dedicated logic registers	2,916 / 114,480 ( 3 % )
    Total registers	2916
    Embedded Multiplier 9-bit elements	0 / 532 ( 0 % )

    去掉两个乘法器:(比较怪异的是,逻辑门数反而增加了,这个很奇怪,难度综合的时候它能合并乘法器?)
    Total logic elements	6,331 / 114,480 ( 6 % )
    Total combinational functions	5,609 / 114,480 ( 5 % )
    Dedicated logic registers	2,917 / 114,480 ( 3 % )
    Total registers	2917
    Total memory bits	150,192 / 3,981,312 ( 4 % )
    Embedded Multiplier 9-bit elements	0 / 532 ( 0 % )

    Total logic elements	6,238 / 114,480 ( 5 % )
    Total combinational functions	5,527 / 114,480 ( 5 % )
    Dedicated logic registers	2,916 / 114,480 ( 3 % )
    Total registers	2916
    Total pins	436 / 529 ( 82 % )
    Total virtual pins	0
    Total memory bits	150,192 / 3,981,312 ( 4 % )
    Embedded Multiplier 9-bit elements	0 / 532 ( 0 % )
    Total PLLs	1 / 4 ( 25 % )
    */

`define USE1DIV_

`ifdef USE1DIV
    wire div_unsign_op = func3[0];
    reg div_unsign;
    reg div_s;
    
    always @(posedge wClk)
    if (state == `RISCVSTATE_EXEC_INST) begin
        div_unsign <= div_unsign_op;
        div_s <= rs1[31] ^ rs2[31];
    end

    div div(wClk, div_unsign_op?rs2:rs2_abs, div_unsign_op?rs1:rs1_abs, div_result_r, mod_result_r);

    assign div_result = div_result_r;
    assign mod_result = mod_result_r;

    wire signed [31:0] div_result_r_sign = div_result_r;

    assign divs_result = div_s ? (-div_result_r_sign) : div_result_r;
    assign mods_result = mod_result_r;
`else
饶先宏's avatar
饶先宏 已提交
261 262 263 264 265 266 267 268
    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;

饶先宏's avatar
饶先宏 已提交
269
`endif
饶先宏's avatar
饶先宏 已提交
270 271 272 273 274 275 276 277 278 279 280
    /* 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
饶先宏's avatar
饶先宏 已提交
281 282
    
    //DEFINE_FUNC(riscv_core_reg_gen_lastv, "state, instr, ldaddr") {
饶先宏's avatar
饶先宏 已提交
283
    always @(posedge wClk)
饶先宏's avatar
饶先宏 已提交
284 285 286 287
    if (state == `RISCVSTATE_WAIT_LD) begin
        lastaddr <= ldaddr;
        if (func3 == 1 && ldaddr[1:0] == 3) begin /* lh */
            lastv <= {24'b0, bReadData[31:24]};
饶先宏's avatar
饶先宏 已提交
288
        end
饶先宏's avatar
饶先宏 已提交
289 290 291 292 293
        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]};
饶先宏's avatar
饶先宏 已提交
294
            else
饶先宏's avatar
饶先宏 已提交
295
                lastv <= {24'b0, bReadData[31:24]};
饶先宏's avatar
饶先宏 已提交
296
        end
饶先宏's avatar
饶先宏 已提交
297 298 299 300 301 302
        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;
饶先宏's avatar
饶先宏 已提交
303
    end
饶先宏's avatar
饶先宏 已提交
304

305 306 307 308 309 310 311 312 313 314
    reg [31:0] newpc;
    always @(opcode or pc or imm or cond or rs1)
    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


饶先宏's avatar
饶先宏 已提交
315
    //DEFINE_FUNC(riscv_core_reg_gen_pc, "nwReset, state, instr, pc, rs1, imm, regrddata") {
饶先宏's avatar
饶先宏 已提交
316 317 318 319 320
    always @(posedge wClk)
    if (!nwReset) begin
        pc <= 32'h00000074;
    end else begin
        if (state == `RISCVSTATE_EXEC_INST) begin
321
            pc <= newpc;
饶先宏's avatar
饶先宏 已提交
322 323 324
        end
    end

饶先宏's avatar
饶先宏 已提交
325 326 327 328
    //DEFINE_FUNC(riscv_core_reg_gen_instr, "state, bReadData") {
    always @(posedge wClk)
    if (state == `RISCVSTATE_READ_REGS)
        instr <= bReadData;
饶先宏's avatar
饶先宏 已提交
329

饶先宏's avatar
饶先宏 已提交
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
    //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
            
345
            writeaddr <= {newwriteaddr[31:2], 2'b00};
饶先宏's avatar
饶先宏 已提交
346 347 348
            writemask <= 4'h0;
            writedata <= rs2;
            write <= 1'b1;
饶先宏's avatar
饶先宏 已提交
349 350 351 352
            case (func3)
            0:/*sb*/ begin
                case (newwriteaddr[1:0])
                0: begin
饶先宏's avatar
饶先宏 已提交
353 354
                    writemask <= 4'he; 
                    writedata <= rs2; 
饶先宏's avatar
饶先宏 已提交
355 356
                end
                1: begin
饶先宏's avatar
饶先宏 已提交
357 358
                    writemask <= 4'hd; 
                    writedata <= {rs2[23:0], 8'h0}; 
饶先宏's avatar
饶先宏 已提交
359 360
                end
                2: begin
饶先宏's avatar
饶先宏 已提交
361 362
                    writemask <= 4'hb; 
                    writedata <= {rs2[15:0], 16'h0};
饶先宏's avatar
饶先宏 已提交
363 364
                end
                3: begin
饶先宏's avatar
饶先宏 已提交
365 366
                    writemask <= 4'h7; 
                    writedata <= {rs2[7:0], 24'h0}; 
饶先宏's avatar
饶先宏 已提交
367 368 369 370 371 372
                end
                endcase
            end
            1:/*sh*/ begin
                case (newwriteaddr[1:0])
                0: begin
饶先宏's avatar
饶先宏 已提交
373 374
                    writemask <= 4'hc; 
                    writedata <= rs2;
饶先宏's avatar
饶先宏 已提交
375 376
                end
                1: begin
饶先宏's avatar
饶先宏 已提交
377 378
                    writemask <= 4'h9; 
                    writedata <= {rs2[23:0], 8'h0}; 
饶先宏's avatar
饶先宏 已提交
379 380
                end
                2: begin
饶先宏's avatar
饶先宏 已提交
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
                    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};
饶先宏's avatar
饶先宏 已提交
407 408 409 410 411
                end
                endcase
            end
            endcase
        end
饶先宏's avatar
饶先宏 已提交
412 413
    end else if (state == `RISCVSTATE_WAIT_ST) begin
        write <= 0;
414
        writeaddr <= {lastaddr[31:2], 2'b0} + 4;
饶先宏's avatar
饶先宏 已提交
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
        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;
饶先宏's avatar
饶先宏 已提交
449 450
    end

饶先宏's avatar
饶先宏 已提交
451 452 453 454 455 456 457
    //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;
458
        `RISCVSTATE_INIT_REGX2: state <= `RISCVSTATE_READ_REGS;
饶先宏's avatar
饶先宏 已提交
459 460 461
        `RISCVSTATE_READ_INST:  state <= `RISCVSTATE_READ_REGS;
        `RISCVSTATE_READ_REGS:   state <= `RISCVSTATE_EXEC_INST;
        `RISCVSTATE_EXEC_INST: begin
饶先宏's avatar
饶先宏 已提交
462
            if (opcode == 5'h00) begin
饶先宏's avatar
饶先宏 已提交
463
                state <= `RISCVSTATE_WAIT_LD;
饶先宏's avatar
饶先宏 已提交
464
            end else if (opcode == 5'h08) begin
饶先宏's avatar
饶先宏 已提交
465
                state <= `RISCVSTATE_WAIT_ST;
饶先宏's avatar
饶先宏 已提交
466
            end else if (opcode == 5'h0c && instr[25] && func3[2] && (rs2 != 0)) begin
饶先宏's avatar
饶先宏 已提交
467
                state <= `RISCVSTATE_WAIT_DIV;
饶先宏's avatar
饶先宏 已提交
468 469 470 471
                divclk <= 31;
            end else if (opcode == 5'h0c && instr[25] && (func3[2]==0) ) begin
                state <= `RISCVSTATE_WAIT_MUL;
                divclk <= 3;
饶先宏's avatar
饶先宏 已提交
472
            end else
473
                state <= `RISCVSTATE_READ_REGS;
饶先宏's avatar
饶先宏 已提交
474 475 476 477 478 479 480 481 482 483 484 485
        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
486
                state <= `RISCVSTATE_READ_INST;
饶先宏's avatar
饶先宏 已提交
487 488
            end
         end
489
        `RISCVSTATE_WAIT_LD2:   state <= `RISCVSTATE_READ_INST;
饶先宏's avatar
饶先宏 已提交
490 491 492 493 494 495 496 497 498 499 500 501
        `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;
饶先宏's avatar
饶先宏 已提交
502
         `RISCVSTATE_WAIT_MUL,
饶先宏's avatar
饶先宏 已提交
503 504
         `RISCVSTATE_WAIT_DIV:  begin
            if (divclk == 0)
505
                state <= `RISCVSTATE_READ_INST;
饶先宏's avatar
饶先宏 已提交
506 507
            else
                divclk <= divclk - 1;
饶先宏's avatar
饶先宏 已提交
508 509
         end
         endcase
饶先宏's avatar
饶先宏 已提交
510
    end
饶先宏's avatar
饶先宏 已提交
511

饶先宏's avatar
饶先宏 已提交
512 513
    //DEFINE_FUNC(riscv_core_gen_imm, "bReadData, state") {
    /* 在RISCVSTATE_READ_REGS周期生成imm */
饶先宏's avatar
饶先宏 已提交
514
    always @(posedge wClk)
饶先宏's avatar
饶先宏 已提交
515 516 517 518 519 520 521 522 523 524
    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]};
饶先宏's avatar
饶先宏 已提交
525
        5'h1c: imm <= {27'b0, bReadData[19:15]};
饶先宏's avatar
饶先宏 已提交
526
        endcase
饶先宏's avatar
饶先宏 已提交
527 528
    end

饶先宏's avatar
饶先宏 已提交
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
    reg[31:0] csr_v;
    reg csr_op;
    always @(func3 or rs1 or csr_r or imm)
    case (func3)
    1: /* CSRRW */  begin csr_v = rs1; csr_op = 1; end
    2: /* CSRRS */  begin csr_v = csr_r | rs1; csr_op = 1;  end
    3: /* CSRRC */  begin csr_v = csr_r & (~rs1); csr_op = 1;  end
    5: /* CSRRWI */ begin csr_v = imm; csr_op = 1;  end
    6: /* CSRRSI */ begin csr_v = csr_r | imm; csr_op = 1;  end
    7: /* CSRRCI */ begin csr_v = csr_r & (~imm); csr_op = 1;  end
    default:        begin csr_v = 0; csr_op = 0; end
    endcase

    //DEFINE_FUNC(riscv_core_gen_csr, "nwReset, ucycle, ucycleh, misa, mcycle, mcycleh, utime,utimeh, uinstret, uinstreth, minstret, minstreth, instr, imm, regrddata") {
    always @(posedge wClk)
    if (nwReset == 0) begin
        misa <= 32'b0100_0000_0001_0000_0001_0001_0000_0000;// RV32IM
        ucycle <= 0;
        ucycleh <= 0;
        mcycle <= 0;
        mcycleh <= 0;
        utime <= 0;
        utimeh <= 0;
        uinstret <= 0;
        uinstreth <= 0;
        minstret <= 0;
        minstreth <= 0;
    end
    else begin
        if (ucycle == 32'hffffffff) begin
            ucycleh <= ucycleh + 1;
            ucycle <= 0;
        end
        else begin
            ucycle <= ucycle + 1;
        end
        if (utime == 32'hffffffff) begin
            utimeh <= utimeh + 1;
            utime <= 0;
        end
        else begin
            utime <= utime + 1;
        end
        if (mcycle == 32'hffffffff) begin
            mcycleh <= mcycleh + 1;
            mcycle <= 0;
        end
        else begin
            mcycle <= mcycle + 1;
        end
        if (state == `RISCVSTATE_EXEC_INST) begin
            if (uinstret == 32'hffffffff) begin
                uinstreth <= uinstreth + 1;
                uinstret <= 0;
            end
            else begin
                uinstret <= uinstret + 1;
            end
            if (minstret == 32'hffffffff) begin
                minstreth <= minstreth + 1;
                minstret <= 0;
            end
            else begin
                minstret <= minstret + 1;
            end
            if (opcode == 5'h1c) begin /* CSR */
                if (csr_op) begin
                    case (instr[31:20]) 
                    12'h301: misa <= csr_v; 
                    12'hc00: ucycle <= csr_v; 
                    12'hc01: utime <= csr_v; 
                    12'hc02: uinstret <= csr_v; 
                    12'hc80: ucycleh <= csr_v; 
                    12'hc81: utimeh <= csr_v; 
                    12'hc82: uinstreth <= csr_v; 
                    12'hb00: mcycle <= csr_v; 
                    12'hb02: minstret <= csr_v; 
                    12'hb80: mcycleh <= csr_v; 
                    12'hb82: minstreth <= csr_v; 
                    endcase
                end
            end
        end
    end


饶先宏's avatar
饶先宏 已提交
615 616 617 618 619 620 621 622 623 624 625 626 627
    //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
628 629 630
    `RISCVSTATE_EXEC_INST,
    `RISCVSTATE_WAIT_LD,
    `RISCVSTATE_WAIT_LD2,
饶先宏's avatar
饶先宏 已提交
631 632
    `RISCVSTATE_WAIT_DIV,
    `RISCVSTATE_WAIT_MUL
633
    : begin
饶先宏's avatar
饶先宏 已提交
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
        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)
677
    if (state == `RISCVSTATE_EXEC_INST) begin
饶先宏's avatar
饶先宏 已提交
678 679 680 681 682 683 684
        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") {
685 686 687 688 689 690 691 692 693
    always @(state or readreg or instr or func3 or ldaddr or bReadData or rd or rs1 or rs2 or rs1_s or rs2_s or lastv or divclk 
              or divs_result or div_result or mods_result or mod_result or muls_result or mulsu_result or mul_result
              or sub_result or add_result 
              or opcode or imm or pc) begin
        dstreg = 0;
        dstvalue = 0;
        case (state)
        `RISCVSTATE_WAIT_LD: begin
            dstreg = readreg;
饶先宏's avatar
饶先宏 已提交
694
            case (func3)
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
            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
饶先宏's avatar
饶先宏 已提交
728 729
            endcase
        end
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
        `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
            dstreg = 0;
            case (func3[1:0])
            0: begin //div
                dstreg = rd;
                dstvalue = divs_result;
            end
            1: begin //divu
                dstreg = rd;
                dstvalue = div_result;
            end
            2: begin//rem
                dstreg = rd;
                dstvalue = mods_result;
            end
            3: begin //remu
                dstreg = rd;
                dstvalue = mod_result;
            end
            endcase
        end 
饶先宏's avatar
饶先宏 已提交
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
        `RISCVSTATE_WAIT_MUL: if (divclk == 0) begin
            dstreg = 0;
            case (func3[1:0])
            0: begin //mul 
                dstvalue = muls_result[31:0];
                dstreg = rd;
            end
            1: begin //mulh 
                dstvalue = muls_result[63:32];
                dstreg = rd;
            end
            2: begin //mulhsu 
                dstvalue = mulsu_result[63:32]; 
                dstreg = rd;
            end
            3: begin //mulhu 
                dstvalue = mul_result[63:32];
                dstreg = rd;
            end
            endcase
        end 
792 793 794 795 796 797 798 799 800
        `RISCVSTATE_EXEC_INST: begin
            dstreg = rd;
            case (opcode)
            5'h0d: begin
                dstvalue = imm;
            end
            5'h05: begin
                dstvalue = imm + pc;
            end
饶先宏's avatar
饶先宏 已提交
801 802 803 804 805 806 807 808
            5'h1c: begin
                if (func3[1:0] != 0) begin /* csr */
                    dstvalue = csr_r;
                end else begin
                    dstreg = 0;
                    dstvalue = 0;
                end
            end
809 810 811 812 813 814 815
            5'h1b: begin
                dstvalue = pc + 4;
            end 
            5'h19: begin
                dstvalue = pc + 4;
            end 
            5'h04: begin /* alui */
饶先宏's avatar
饶先宏 已提交
816
                case (func3)
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
                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)
饶先宏's avatar
饶先宏 已提交
832
                    /*
833 834
                    0: begin //mul 
                        dstvalue = muls_result[31:0];
饶先宏's avatar
饶先宏 已提交
835
                    end
836 837
                    1: begin //mulh 
                        dstvalue = muls_result[63:32];
饶先宏's avatar
饶先宏 已提交
838
                    end
839 840
                    2: begin //mulhsu 
                        dstvalue = mulsu_result[63:32]; 
饶先宏's avatar
饶先宏 已提交
841
                    end
842 843
                    3: begin //mulhu 
                        dstvalue = mul_result[63:32];
饶先宏's avatar
饶先宏 已提交
844
                    end
饶先宏's avatar
饶先宏 已提交
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
                      */  
                    0: begin //mul 
                        dstreg = 0;
                        dstvalue = 0;
                    end
                    1: begin //mulh 
                        dstreg = 0;
                        dstvalue = 0;
                    end
                    2: begin //mulhsu 
                        dstreg = 0;
                        dstvalue = 0;
                    end
                    3: begin //mulhu 
                        dstreg = 0;
                        dstvalue = 0;
                    end
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
                    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;
饶先宏's avatar
饶先宏 已提交
900 901 902 903
                            //rs1 - rs2;//sub_result;
                        else
                            dstvalue = add_result;
                            //rs1 + rs2;//add_result;
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
                    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
饶先宏's avatar
饶先宏 已提交
930 931
                end
            end
932 933 934 935 936
            default: begin
                dstreg = 0;
                dstvalue = 0;
            end 
            endcase
饶先宏's avatar
饶先宏 已提交
937 938 939
        end
        endcase
    end
饶先宏's avatar
饶先宏 已提交
940 941

    //DEFINE_FUNC(riscv_core_read_sig, "state, pc, instr, bReadData, rs1") {
942 943
    always @(state or pc or opcode or imm or rs1 or func3 or ldaddr or newpc)
    begin
饶先宏's avatar
饶先宏 已提交
944 945
        wRead = 0;
        bReadAddr = 0;
946 947 948 949 950 951
        case (state)
        `RISCVSTATE_INIT_REGX2: begin
            wRead = 1;
            bReadAddr = pc;
        end
        `RISCVSTATE_READ_INST: begin
饶先宏's avatar
饶先宏 已提交
952 953
            wRead = 1;
            bReadAddr = pc;
954 955
        end 
        `RISCVSTATE_EXEC_INST: begin
饶先宏's avatar
饶先宏 已提交
956 957 958 959
            if (opcode == 5'h00) begin
                /* ld inst */
                bReadAddr = rs1 + imm;
                wRead = 1;
960 961 962 963 964 965
            end else if (opcode == 5'h08) begin
                wRead = 0;
                bReadAddr = 0;
            end else begin
                wRead = 1;
                bReadAddr = newpc;
饶先宏's avatar
饶先宏 已提交
966
            end
967 968
        end 
        `RISCVSTATE_WAIT_LD: begin
饶先宏's avatar
饶先宏 已提交
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
            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
985 986 987 988
        end 
        default: begin
            wRead = 0;
            bReadAddr = 0;
饶先宏's avatar
饶先宏 已提交
989
        end
990
        endcase
饶先宏's avatar
饶先宏 已提交
991
    end
饶先宏's avatar
饶先宏 已提交
992 993

endmodule