欢迎来到飞鸟慕鱼博客,开始您的技术之旅!
当前位置: 首页知识笔记正文

plc基本指令的编程实验,侯集实验中学

终极管理员 知识笔记 545阅读

在借鉴了友佬的代码后终于是跑通了测试。

1.



2.



4.


5.


6.


还需要改一个

assign sr64_result  {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0]; //rj >> i5
代码 mycpu_top.v
module mycpu_top(    input  wire        clk,    input  wire        resetn,    // inst sram interface    output wire        inst_sram_we,    output wire [31:0] inst_sram_addr,    output wire [31:0] inst_sram_wdata,    input  wire [31:0] inst_sram_rdata,    // data sram interface    output wire        data_sram_we,    output wire [31:0] data_sram_addr,    output wire [31:0] data_sram_wdata,    input  wire [31:0] data_sram_rdata,    // trace debug interface    output wire [31:0] debug_wb_pc,    output wire [ 3:0] debug_wb_rf_we,    output wire [ 4:0] debug_wb_rf_wnum,    output wire [31:0] debug_wb_rf_wdata);reg         reset;always (posedge clk) reset < ~resetn;reg         valid;always (posedge clk) begin    if (reset) begin        valid < 1b0;    end    else begin        valid < 1b1;    endendwire [31:0] seq_pc;wire [31:0] nextpc;wire        br_taken;wire [31:0] br_target;wire [31:0] inst;reg  [31:0] pc;wire [11:0] alu_op;wire        load_op;wire        src1_is_pc;wire        src2_is_imm;wire        res_from_mem;wire        dst_is_r1;wire        gr_we;wire        mem_we;wire        src_reg_is_rd;wire [4: 0] dest;wire [31:0] rj_value;wire [31:0] rkd_value;wire [31:0] imm;wire [31:0] br_offs;wire [31:0] jirl_offs;wire [ 5:0] op_31_26;wire [ 3:0] op_25_22;wire [ 1:0] op_21_20;wire [ 4:0] op_19_15;wire [ 4:0] rd;wire [ 4:0] rj;wire [ 4:0] rk;wire [11:0] i12;wire [19:0] i20;wire [15:0] i16;wire [25:0] i26;wire [63:0] op_31_26_d;wire [15:0] op_25_22_d;wire [ 3:0] op_21_20_d;wire [31:0] op_19_15_d;wire        inst_add_w;wire        inst_sub_w;wire        inst_slt;wire        inst_sltu;wire        inst_nor;wire        inst_and;wire        inst_or;wire        inst_xor;wire        inst_slli_w;wire        inst_srli_w;wire        inst_srai_w;wire        inst_addi_w;wire        inst_ld_w;wire        inst_st_w;wire        inst_jirl;wire        inst_b;wire        inst_bl;wire        inst_beq;wire        inst_bne;wire        inst_lu12i_w;wire        need_ui5;wire        need_si12;wire        need_si16;wire        need_si20;wire        need_si26;wire        src2_is_4;wire [ 4:0] rf_raddr1;wire [31:0] rf_rdata1;wire [ 4:0] rf_raddr2;wire [31:0] rf_rdata2;wire        rf_we   ;wire [ 4:0] rf_waddr;wire [31:0] rf_wdata;wire [31:0] alu_src1   ;wire [31:0] alu_src2   ;wire [31:0] alu_result ;wire [31:0] final_result;wire [31:0] mem_result;assign seq_pc        pc  32h4;assign nextpc        br_taken ? br_target : seq_pc;always (posedge clk) begin    if (reset) begin        pc < 32h1bfffffc;     //trick: to make nextpc be 0x1c000000 during reset     end    else begin        pc < nextpc;    endendassign inst_sram_we     1b0;assign inst_sram_addr   pc;assign inst_sram_wdata  32b0;assign inst             inst_sram_rdata;assign op_31_26   inst[31:26];assign op_25_22   inst[25:22];assign op_21_20   inst[21:20];assign op_19_15   inst[19:15];assign rd    inst[ 4: 0];assign rj    inst[ 9: 5];assign rk    inst[14:10];assign i12   inst[21:10];assign i20   inst[24: 5];assign i16   inst[25:10];assign i26   {inst[ 9: 0], inst[25:10]};decoder_6_64 u_dec0(.in(op_31_26 ), .out(op_31_26_d ));decoder_4_16 u_dec1(.in(op_25_22 ), .out(op_25_22_d ));decoder_2_4  u_dec2(.in(op_21_20 ), .out(op_21_20_d ));decoder_5_32 u_dec3(.in(op_19_15 ), .out(op_19_15_d ));assign inst_add_w   op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h00];assign inst_sub_w   op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h02];assign inst_slt     op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h04];assign inst_sltu    op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h05];assign inst_nor     op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h08];assign inst_and     op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h09];assign inst_or      op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h0a];assign inst_xor     op_31_26_d[6h00] & op_25_22_d[4h0] & op_21_20_d[2h1] & op_19_15_d[5h0b];assign inst_slli_w  op_31_26_d[6h00] & op_25_22_d[4h1] & op_21_20_d[2h0] & op_19_15_d[5h01];assign inst_srli_w  op_31_26_d[6h00] & op_25_22_d[4h1] & op_21_20_d[2h0] & op_19_15_d[5h09];assign inst_srai_w  op_31_26_d[6h00] & op_25_22_d[4h1] & op_21_20_d[2h0] & op_19_15_d[5h11];assign inst_addi_w  op_31_26_d[6h00] & op_25_22_d[4ha];assign inst_ld_w    op_31_26_d[6h0a] & op_25_22_d[4h2];assign inst_st_w    op_31_26_d[6h0a] & op_25_22_d[4h6];assign inst_jirl    op_31_26_d[6h13];assign inst_b       op_31_26_d[6h14];assign inst_bl      op_31_26_d[6h15];assign inst_beq     op_31_26_d[6h16];assign inst_bne     op_31_26_d[6h17];assign inst_lu12i_w op_31_26_d[6h05] & ~inst[25];assign alu_op[ 0]  inst_add_w | inst_addi_w | inst_ld_w | inst_st_w                    | inst_jirl | inst_bl;// assign alu_op[ 0]  inst_add_w | inst_addi_w | inst_ld_w | inst_st_w//                     | inst_jirl | inst_bl | inst_b | inst_beq | inst_bne;assign alu_op[ 1]  inst_sub_w;assign alu_op[ 2]  inst_slt;assign alu_op[ 3]  inst_sltu;assign alu_op[ 4]  inst_and;assign alu_op[ 5]  inst_nor;assign alu_op[ 6]  inst_or;assign alu_op[ 7]  inst_xor;assign alu_op[ 8]  inst_slli_w;assign alu_op[ 9]  inst_srli_w;assign alu_op[10]  inst_srai_w;assign alu_op[11]  inst_lu12i_w;assign need_ui5     inst_slli_w | inst_srli_w | inst_srai_w;assign need_si12    inst_addi_w | inst_ld_w | inst_st_w;assign need_si16    inst_jirl | inst_beq | inst_bne;assign need_si20    inst_lu12i_w;assign need_si26    inst_b | inst_bl;assign src2_is_4    inst_jirl | inst_bl;//看看是不是要加4.assign imm  src2_is_4 ? 32h4                      :             need_si20 ? {i20[19:0], 12b0}         :/*need_ui5 || need_si12*/{{20{i12[11]}}, i12[11:0]} ;assign br_offs  need_si26 ? {{ 4{i26[25]}}, i26[25:0], 2b0} :                             {{14{i16[15]}}, i16[15:0], 2b0} ;// assign br_offs  {32{need_si26}} & {{ 4{i26[25]}}, i26[25:0], 2b0} |//                  {32{need_si16}} & {{14{i16[15]}}, i16[15:0], 2b0} ;assign jirl_offs  {{14{i16[15]}}, i16[15:0], 2b0};assign src_reg_is_rd  inst_beq | inst_bne | inst_st_w ;assign load_op        inst_ld_w;// 从这两个信号可以看出不同类型的指令数据通路是不一样的assign src1_is_pc     inst_jirl | inst_bl;assign src2_is_imm    inst_slli_w |                       inst_srli_w |                       inst_srai_w |                       inst_addi_w |                       inst_ld_w   |                       inst_st_w   |                       inst_lu12i_w|                       inst_jirl   |                       inst_bl     ;assign res_from_mem   inst_ld_w;assign dst_is_r1      inst_bl;//  是否需要写入通用寄存器assign gr_we          ~inst_st_w & ~inst_beq & ~inst_bne & ~inst_b;assign mem_we         inst_st_w;assign dest           dst_is_r1 ? 5d1 : rd;assign rf_raddr1  rj;assign rf_raddr2  src_reg_is_rd ? rd :rk;regfile u_regfile(    .clk    (clk      ),    .raddr1 (rf_raddr1),    .rdata1 (rf_rdata1),    .raddr2 (rf_raddr2),    .rdata2 (rf_rdata2),    .we     (rf_we    ),    .waddr  (rf_waddr ),    .wdata  (rf_wdata )    );assign rj_value   rf_rdata1;assign rkd_value  rf_rdata2;assign rj_eq_rd  (rj_value  rkd_value);assign br_taken  (   inst_beq  &&  rj_eq_rd                   || inst_bne  && !rj_eq_rd                   || inst_jirl                   || inst_bl                   || inst_b                  ) && valid;assign br_target  (inst_beq || inst_bne || inst_bl || inst_b) ? (pc  br_offs) :                                                   /*inst_jirl*/ (rj_value  jirl_offs);assign alu_src1  src1_is_pc  ? pc[31:0] : rj_value;assign alu_src2  src2_is_imm ? imm : rkd_value;alu u_alu(    .alu_op     (alu_op    ),    .alu_src1   (alu_src1 ),//alu_src2    .alu_src2   (alu_src2  ),    .alu_result (alu_result)    );assign data_sram_we     mem_we && valid;assign data_sram_addr   alu_result;assign data_sram_wdata  rkd_value;assign mem_result    data_sram_rdata;assign final_result  res_from_mem ? mem_result : alu_result;assign rf_we     gr_we;assign rf_waddr  dest;assign rf_wdata  final_result;// debug info generateassign debug_wb_pc        pc;assign debug_wb_rf_we    {4{rf_we}};assign debug_wb_rf_wnum   dest;assign debug_wb_rf_wdata  final_result;endmodule
alu.v
module alu(  input  wire [11:0] alu_op,  input  wire [31:0] alu_src1,  input  wire [31:0] alu_src2,  output wire [31:0] alu_result);wire op_add;   //add operationwire op_sub;   //sub operationwire op_slt;   //signed compared and set less thanwire op_sltu;  //unsigned compared and set less thanwire op_and;   //bitwise andwire op_nor;   //bitwise norwire op_or;    //bitwise orwire op_xor;   //bitwise xorwire op_sll;   //logic left shiftwire op_srl;   //logic right shiftwire op_sra;   //arithmetic right shiftwire op_lui;   //Load Upper Immediate// control code decompositionassign op_add   alu_op[ 0];assign op_sub   alu_op[ 1];assign op_slt   alu_op[ 2];assign op_sltu  alu_op[ 3];assign op_and   alu_op[ 4];assign op_nor   alu_op[ 5];assign op_or    alu_op[ 6];assign op_xor   alu_op[ 7];assign op_sll   alu_op[ 8];assign op_srl   alu_op[ 9];assign op_sra   alu_op[10];assign op_lui   alu_op[11];wire [31:0] add_sub_result;wire [31:0] slt_result;wire [31:0] sltu_result;wire [31:0] and_result;wire [31:0] nor_result;wire [31:0] or_result;wire [31:0] xor_result;wire [31:0] lui_result;wire [31:0] sll_result;wire [63:0] sr64_result;wire [31:0] sr_result;// 32-bit adderwire [31:0] adder_a;wire [31:0] adder_b;wire        adder_cin;wire [31:0] adder_result;wire        adder_cout;assign adder_a    alu_src1;assign adder_b    (op_sub | op_slt | op_sltu) ? ~alu_src2 : alu_src2;  //src1 - src2 rj-rkassign adder_cin  (op_sub | op_slt | op_sltu) ? 1b1      : 1b0;assign {adder_cout, adder_result}  adder_a  adder_b  adder_cin;// ADD, SUB resultassign add_sub_result  adder_result;// SLT resultassign slt_result[31:1]  31b0;   //rj < rk 1assign slt_result[0]     (alu_src1[31] & ~alu_src2[31])                        | ((alu_src1[31] ~^ alu_src2[31]) & adder_result[31]);// SLTU resultassign sltu_result[31:1]  31b0;assign sltu_result[0]     ~adder_cout;// bitwise operationassign and_result  alu_src1 & alu_src2;assign or_result   alu_src1 | alu_src2;assign nor_result  ~or_result;assign xor_result  alu_src1 ^ alu_src2;assign lui_result  alu_src2;// SLL resultassign sll_result  alu_src1 << alu_src2[4:0];   //rj << i5// assign sll_result  alu_src2 << alu_src1[4:0];  // SRL, SRA resultassign sr64_result  {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0]; //rj >> i5assign sr_result    sr64_result[31:0];// final result muxassign alu_result  ({32{op_add|op_sub}} & add_sub_result)                  | ({32{op_slt       }} & slt_result)                  | ({32{op_sltu      }} & sltu_result)                  | ({32{op_and       }} & and_result)                  | ({32{op_nor       }} & nor_result)                  | ({32{op_or        }} & or_result)                  | ({32{op_xor       }} & xor_result)                  | ({32{op_lui       }} & lui_result)                  | ({32{op_sll       }} & sll_result)                  | ({32{op_srl|op_sra}} & sr_result);endmodule

标签:
声明:无特别说明,转载请标明本文来源!