Mips架构32位CPU实现(31条指令)Verilog

CPU模块设计

cpu模块主要是将各个模块组合正在一起
数据通路图:

详见代码在这里插入图片描述

`timescale 1ns / 1ps

module cpu(
    input clk,				//时钟沿信号
    input rst,				//复位信号
    output [31:0] pcdata,	//指令码地址pc
    input [31:0] inst,		//输入的指令码
    input [31:0] rdata,		//从ram读入的数据
    output [31:0] addr,		//写入ram的地址
    output [31:0] wdata,	//写入ram的数据
    output im_r,			//指令寄存器读信号
    output dm_cs,			//
    output dm_r,			//数据寄存器读信号
    output dm_w,			//数据寄存器写信号
    output [5:0] op_out,	//调试输出用...
    output Z            	//调试输出用...
    );
     
     wire [31:0] npc_out;
     wire [31:0] npc_in;
         
     ADDU NPC(				//NPC模块
     .a(npc_in),			//功能:每次将pc+4,指向下一条指令地址
     .b(32'd4),
     .c(npc_out)
     );
     
     wire [31:0] mux1_in1;
     wire [31:0] mux1_in2;
     wire [31:0] mux1_out;
     wire mux1_m;
     MUX MUX1(				//数据选择器
     .m(mux1_m),			//功能:根据不同的信号选择不用的输入作为输出
     .data_in1(mux1_in1),
     .data_in2(mux1_in2),
     .data_out(mux1_out)
     );
     
     wire [31:0] mux3_in1;
     wire [31:0] mux3_in2;
     wire [31:0] mux3_out;
     wire mux3_m;			//数据选择器
     MUX MUX3(
     .m(mux3_m),
     .data_in1(mux3_in1),
     .data_in2(mux3_in2),
     .data_out(mux3_out)
     );
     
     wire [31:0] mux4_in1;
     wire [31:0] mux4_in2;
     wire [31:0] mux4_out;
     wire mux4_m;			//数据选择器
     MUX MUX4(
     .m(mux4_m),
     .data_in1(mux4_in1),
     .data_in2(mux4_in2),
     .data_out(mux4_out)
     );
     
     wire [31:0] mux5_in1;
     wire [31:0] mux5_in2;
     wire [31:0] mux5_out;
     wire mux5_m;
     MUX MUX5(				//数据选择器
     .m(mux5_m),
     .data_in1(mux5_in1),
     .data_in2(mux5_in2),
     .data_out(mux5_out)
     );
     
     wire [31:0] mux6_in1;
     wire [31:0] mux6_in2;
     wire [31:0] mux6_out;
     wire mux6_m;
     MUX MUX6(				//数据选择器
     .m(mux6_m),
     .data_in1(mux6_in1),
     .data_in2(mux6_in2),
     .data_out(mux6_out)
     );
     
     wire [31:0] mux7_in1;
     wire [31:0] mux7_in2;
     wire [31:0] mux7_out;
     wire mux7_m;
     MUX MUX7(				//数据选择器
     .m(mux7_m),
     .data_in1(mux7_in1),
     .data_in2(mux7_in2),
     .data_out(mux7_out)
     );
     
     wire [31:0] mux8_in1;
     wire [31:0] mux8_in2;
     wire [31:0] mux8_out;
     wire mux8_m;
     MUX MUX8(				//数据选择器
     .m(mux8_m),
     .data_in1(mux8_in1),
     .data_in2(mux8_in2),
     .data_out(mux8_out)
     );
     
     wire [31:0] mux2_in1;
     wire [31:0] mux2_in2;
     wire [31:0] mux2_in3;
     wire [31:0] mux2_out;
     wire [1:0] mux2_m;
     MUXS MUX2(				//数据选择器
     .m(mux2_m),
     .data_in1(mux2_in1),
     .data_in2(mux2_in2),
     .data_in3(mux2_in3),
     .data_out(mux2_out)
     );
     
     wire [4:0] ext5_in;
     wire [31:0] ext5_out;
     wire ext5_c;
     Ext_imm5 ext5(			//数据扩充器
     .idata(ext5_in),		//将数据扩充为32位
     .odata(ext5_out),
     .ca(ext5_c)
     );
     
     wire [15:0] ext16_in;
     wire [31:0] ext16_out;
     wire ext16_c;
     Ext_imm16 ext16(		//数据扩充器
     .idata(ext16_in),
     .odata(ext16_out),
     .ca(ext16_c)
     );
     
     wire [15:0] ext18_in;
     wire [31:0] ext18_out;
     wire ext18_c;
     Ext_imm18 ext18(		//数据扩充器
     .idata(ext18_in),
     .odata(ext18_out),
     .ca(ext18_c)
     );
     
 //    wire pc_ena;
     wire pc_clk;
     wire pc_rst;
     assign pc_rst=rst;
     wire [31:0] pc_data_in;
     wire [31:0] pc_data_out;
     wire [3:0] pc_data31_28;
     PC_Reg PC(				//PC寄存器
     .clk(pc_clk),			//功能:存放下一条指令的地址
     .rst(pc_rst),
     .ena(1'b1),
     .data_in(pc_data_in),
     .data_out(pc_data_out),
     .pc31_28(pc_data31_28)
     );
     
//     wire imem_wena;
 //    assign imem_wena=0;
//     wire [31:0] imem_addr;
 //    wire [31:0] imem_data_in;
//     assign imem_data_in=32'b0;
     wire [31:0] imem_data_out;
     wire [25:0] target=imem_data_out[25:0];
     wire [4:0] sa=imem_data_out[10:6];
     wire [4:0] Rsc=imem_data_out[25:21];
     wire [4:0] Rtc=imem_data_out[20:16];
     wire [4:0] Rdc=imem_data_out[15:11];
     wire [5:0] op=imem_data_out[31:26];
     wire [5:0] func=imem_data_out[5:0];
     wire [15:0] imm16=imem_data_out[15:0];
/*     IMEM imem(
     .clk(clk),
     .wena(imem_wena),
     .addr(imem_addr),
     .data_in(imem_data_in),
     .data_out(imem_data_out)
     );*/
     
     
     wire rf_clk;
     wire rf_rst;
     assign rf_rst=rst;
     wire rf_we;
     wire [4:0]rf_rsc;
     wire [4:0]rf_rtc;
     wire [4:0]rf_rdc;
     wire [31:0]rf_rd;
     wire [31:0]rf_rs;
     wire [31:0]rf_rt;
     RegFiles cpu_ref(		//通用寄存器模块
     .clk(rf_clk),
     .rst(rf_rst),
     .we(rf_we),
     .raddr1(rf_rsc),
     .rdata1(rf_rs),
     .raddr2(rf_rtc),
     .rdata2(rf_rt),
     .waddr(rf_rdc),
     .wdata(rf_rd)
     );
     
     wire [31:0] alu_a;
     wire [31:0] alu_b;
     wire [31:0] alu_r;
     wire [3:0] aluc;
     wire z;
     wire c;
     wire n;
     wire o;
     alu ALU(				//ALU模块
     .a(alu_a),
     .b(alu_b),
     .r(alu_r),
     .aluc(aluc),
     .zero(z),
     .carry(c),
     .negative(n),
     .overflow(o)
     );
     
     wire [31:0] add_a;
     wire [31:0] add_b;
     wire [31:0] add_c;
     ADD add(
     .a(add_a),
     .b(add_b),
     .c(add_c)
     );
     
     
     wire dmem_cs;
     wire dmem_we;
     wire dmem_re;
     wire [31:0] dmem_addr;
     wire [31:0] dmem_data_in;
     wire [31:0] dmem_data_out;
 //    wire [31:0] dmem_data;
/*     DMEM dmem(
     .clk(clk),
     .cs(dmem_cs),
     .we(dmem_we),
     .re(dmem_re),
     .addr(dmem_addr),
     .data_in(dmem_data_in),
     .data_out(dmem_data_out)
     );  */
     wire [31:0] j_jal={npc_out[31:28],imem_data_out[25:0],2'b0};
     
     assign npc_in=pc_data_out;
     assign mux1_in1=j_jal;
     assign mux1_in2=mux5_out;
     assign add_b=npc_out;
     assign mux5_in1=npc_out;
     assign mux5_in2=add_c;
     assign add_a=ext18_out;
     assign ext18_in=imm16;
     assign ext16_in=imm16;
     assign ext5_in=sa;
 //    assign imem_addr=pc_data_out;
     assign mux7_in1=rf_rs;
     assign mux7_in2=mux1_out;
     assign pc_data_in=mux7_out;
     assign mux6_in1=rf_rtc;
     assign mux6_in2=Rdc;//assign mux6_in2=rf_rdc;//
     assign mux8_in1=mux6_out;
     assign mux8_in2=32'd31;
     assign rf_rdc=mux8_out;
     assign rf_rsc=Rsc;
     assign rf_rtc=Rtc;
     assign rf_rd=mux2_out;
     assign mux3_in1=ext5_out;
     assign mux3_in2=rf_rs;
     assign mux4_in1=rf_rt;
     assign mux4_in2=ext16_out;
     assign alu_a=mux3_out;
     assign alu_b=mux4_out;
     assign dmem_addr=alu_r;
     assign mux2_in1=dmem_data_out;
     assign dmem_data_in=rf_rt;
     assign mux2_in2=npc_out;
     assign mux2_in3=alu_r;
     
 /*    wire [5:0] op;
     wire [5:0] func;
     wire z;*/
 
 
     wire PC_CLK;
     wire IM_R;
     wire M3;
     wire M4;
     wire [3:0] ALUC;
     wire M2_0;
     wire M2_1;
     wire M6;
     wire RF_W;
     wire RF_CLK;
     wire M5;
     wire M1;
     wire DM_CS;
     wire DM_R;
     wire DM_W;
     wire M7;
     wire M8;
     wire Ext5_C;
     wire Ext16_C;
     wire Ext18_C;
     
     control cpucon(		//控制器模块
     .op(op),
     .func(func),
     .z(z),
     .clk(clk),
     .PC_CLK(PC_CLK),
     .IM_R(IM_R),
     .M3(M3),
     .M4(M4),
     .ALUC(ALUC),
     .M2_0(M2_0),
     .M2_1(M2_1),
     .M6(M6),
     .RF_W(RF_W),
     .RF_CLK(RF_CLK),
     .M5(M5),
     .M1(M1),
     .DM_CS(DM_CS),
     .DM_R(DM_R),
     .DM_W(DM_W),
     .M7(M7),
     .M8(M8),
     .Ext5_C(Ext5_C),
     .Ext16_C(Ext16_C),
     .Ext18_C(Ext18_C)    
     );
     
     assign pc_clk=PC_CLK;
  //   assign =IM_R;
     assign mux3_m=M3;
     assign mux4_m=M4;
     assign aluc=ALUC;
     assign mux2_m={M2_0,M2_1};
     assign mux6_m=M6;
     assign rf_we=RF_W;
     assign rf_clk=RF_CLK;
     assign mux5_m=M5;
     assign mux1_m=M1;
     assign dmem_cs=DM_CS;
     assign dmem_we=DM_W;
     assign dmem_re=DM_R;
     assign mux7_m=M7;
     assign mux8_m=M8;
     assign ext5_c=Ext5_C;
     assign ext16_c=Ext16_C;
     assign ext18_c=Ext18_C;
    
    
    assign imem_data_out=inst;
    assign pcdata=pc_data_out;
    assign addr=dmem_addr;
    assign wdata=dmem_data_in;
    assign dmem_data_out=rdata;
    assign dm_cs=DM_CS;
    assign dm_w=DM_W;
    assign dm_r=DM_R;
    assign op_out=op;
    assign Z=z;
 endmodule


控制器模块

控制器模块识别输入机器码,并输出控制信号,控制各个模块的运行
各指令(已包括54条指令)所需控制信号如下图所示
在这里插入图片描述

`timescale 1ns / 1ps

module control(
    input [5:0] op,
    input [5:0] func,
    input z,
    input clk,
    output PC_CLK,
    output IM_R,
    output M3,
    output M4,
    output [3:0] ALUC,
    output M2_0,
    output M2_1,
    output M6,
    output RF_W,
    output RF_CLK,
    output M5,
    output M1,
    output DM_CS,
    output DM_R,
    output DM_W,
    output M7,
    output M8,
    output Ext5_C,
    output Ext16_C,
    output Ext18_C
    );
    wire r_type=~|op;
    wire i_add=r_type&func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
    wire i_addu=r_type&func[5]&~func[4]&~func[3]&~func[2]&~func[1]&func[0];
    wire i_sub=r_type&func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
    wire i_subu=r_type&func[5]&~func[4]&~func[3]&~func[2]&func[1]&func[0];
    wire i_and=r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&~func[0];
    wire i_or=r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&func[0];
    wire i_xor=r_type&func[5]&~func[4]&~func[3]&func[2]&func[1]&~func[0];
    wire i_nor=r_type&func[5]&~func[4]&~func[3]&func[2]&func[1]&func[0];
    wire i_slt=r_type&func[5]&~func[4]&func[3]&~func[2]&func[1]&~func[0];
    wire i_sltu=r_type&func[5]&~func[4]&func[3]&~func[2]&func[1]&func[0];
    wire i_sll=r_type&~func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
    wire i_srl=r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
    wire i_sra=r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&func[0];
    wire i_sllv=r_type&~func[5]&~func[4]&~func[3]&func[2]&~func[1]&~func[0];
    wire i_srlv=r_type&~func[5]&~func[4]&~func[3]&func[2]&func[1]&~func[0];
    wire i_srav=r_type&~func[5]&~func[4]&~func[3]&func[2]&func[1]&func[0];
    wire i_jr=r_type&~func[5]&~func[4]&func[3]&~func[2]&~func[1]&~func[0];
    wire i_addi=~op[5]&~op[4]&op[3]&~op[2]&~op[1]&~op[0];
    wire i_addiu=~op[5]&~op[4]&op[3]&~op[2]&~op[1]&op[0];
    wire i_andi=~op[5]&~op[4]&op[3]&op[2]&~op[1]&~op[0];
    wire i_ori=~op[5]&~op[4]&op[3]&op[2]&~op[1]&op[0];
    wire i_xori=~op[5]&~op[4]&op[3]&op[2]&op[1]&~op[0];
    wire i_lui=~op[5]&~op[4]&op[3]&op[2]&op[1]&op[0];
    wire i_lw=op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
    wire i_sw=op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
    wire i_beq=~op[5]&~op[4]&~op[3]&op[2]&~op[1]&~op[0];
    wire i_bne=~op[5]&~op[4]&~op[3]&op[2]&~op[1]&op[0];
    wire i_slti=~op[5]&~op[4]&op[3]&~op[2]&op[1]&~op[0];
    wire i_sltiu=~op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
    wire i_j=~op[5]&~op[4]&~op[3]&~op[2]&op[1]&~op[0];
    wire i_jal=~op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
    
    assign PC_CLK=clk;
    assign IM_R=1;
    assign M3=(i_sll+i_srl+i_sra)?0:1;
    assign M4=i_addi+i_addiu+i_andi+i_ori+i_xori+i_lui+i_lw+i_sw+i_slti+i_sltiu+i_j+i_jal+i_jr;
    assign M2_0=~(i_lw+i_jal);
    assign M2_1=~i_lw;
    assign M6=i_add+i_addu+i_sub+i_subu+i_and+i_or+i_xor+i_nor+i_slt+i_sltu+i_sll+i_srl+i_sra+i_sllv+i_srlv+i_srav;
    assign RF_W=~(i_sw+i_beq+i_bne+i_j);
 //   assign RF_CLK=~(i_sw+i_beq+i_bne+i_j)&clk;
    assign RF_CLK=clk;
    assign M5=((i_beq&z)+(i_bne&(~z)));
 //   assign M5=i_beq&z;
    assign M1=~(i_j+i_jal+i_jr);
    assign DM_CS=i_lw+i_sw;
    assign DM_R=i_lw;
    assign DM_W=i_sw;
    assign M7=~i_jr;
    assign M8=i_jal;
    assign Ext5_C=0;
    assign Ext16_C=i_addi+i_addiu+i_slti+i_sltiu;
    assign Ext18_C=1;
    
    reg [3:0] aluc;
    always@(*)begin
        if(i_add) aluc=4'b0010;
        else if(i_addu) aluc=4'b0000;
        else if(i_sub) aluc=4'b0011;
        else if(i_subu) aluc=4'b0001;
        else if(i_and) aluc=4'b0100;
        else if(i_or) aluc=4'b0101;
        else if(i_xor) aluc=4'b0110;
        else if(i_nor) aluc=4'b0111;
        else if(i_slt) aluc=4'b1011;
        else if(i_sltu) aluc=4'b1010;
        else if(i_sll) aluc=4'b1110;
        else if(i_srl) aluc=4'b1101;
        else if(i_sra) aluc=4'b1100;
        else if(i_sllv) aluc=4'b1110;
        else if(i_srlv) aluc=4'b1101;
        else if(i_srav) aluc=4'b1100;
        else if(i_addi) aluc=4'b0010;
        else if(i_addiu) aluc=4'b0000;
        else if(i_andi) aluc=4'b0100;
        else if(i_ori) aluc=4'b0101;
        else if(i_xori) aluc=4'b0110;
        else if(i_lui) aluc=4'b1000;
        else if(i_beq) aluc=4'b0011;
        else if(i_bne) aluc=4'b0011;
        else if(i_slti) aluc=4'b1011;
        else if(i_sltiu) aluc=4'b1010;
        else aluc=4'b0000;
    end
    
    assign ALUC=aluc;
    
endmodule

ALU模块

ALU模块主要实现基本的运算操作:加法、减法、移位等

`timescale 1ns / 1ps
module alu(
    input [31:0] a,
    input [31:0] b,
    input [3:0] aluc,
    output reg [31:0] r,
    output reg zero,
    output reg carry,
    output reg negative,
    output reg overflow
    );
    reg [32:0] tempa;
    reg [32:0] tempb;
    reg [32:0] temp;
    reg c;
    integer i;
    initial begin
    zero=0;
    carry=0;
    negative=0;
    overflow=0;
    end
    always @(*)
    begin
      if(aluc[3]==0&&aluc[2]==0&&aluc[1]==0&&aluc[0]==0)
            begin
               {carry,r}=a+b;  
               if(r[31]==1) negative=1;
               else negative=0; 
               if(r==0) zero=1;
               else zero=0;        
            end
      else if(aluc[3]==0&&aluc[2]==0&&aluc[1]==1&&aluc[0]==0)
            begin
                r=a+b;
                if(a[31]==b[31]) begin
                    if(r[31]==a[31])
                        overflow=0;
                    else
                        overflow=1;
                 end
                 if(r[31]==1) negative=1;
                 else negative=0;
                 if(r==0) zero=1;
                 else zero=0;  
            end
      else if(aluc[3]==0&&aluc[2]==0&&aluc[1]==0&&aluc[0]==1)
        begin
            {carry,r}=a-b;   
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==0&&aluc[2]==0&&aluc[1]==1&&aluc[0]==1)
        begin
            r=a-b;
            if(a[31]!=b[31]) begin
                if(r[31]==a[31])
                    overflow=0;
                else
                    overflow=1;
                end
            else overflow=0;
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==0&&aluc[0]==0)
        begin
            r=a&b;
            if(r[31]==1) negative=1;
            else negative=0;  
            if(r==0) zero=1;
            else zero=0;            
        end
      else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==0&&aluc[0]==1)
        begin
            r=a|b;
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==1&&aluc[0]==0)
        begin
            r=a^b;
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==1&&aluc[0]==1)
        begin
            r=~(a|b);
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==1&&aluc[2]==0&&aluc[1]==0)
        begin
            r={b[15:0],16'b0};
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==1&&aluc[2]==0&&aluc[1]==1&&aluc[0]==1)
        begin
            if(a[31]==0&&b[31]==0) begin
                if(a<b) begin
                    r=1;
                    negative=1;
                    end
                else begin
                    r=0;
                    negative=0;
                    end
                end
            else if(a[31]==1&&b[31]==1) begin
                if(a<b) begin
                    r=0;
                    negative=0;
                    end
                else begin
                    r=1;
                    negative=1;
                    end
                end
            else if(a[31]==0&&b[31]==1) begin
                r=0;
                negative=0;
                end
            else if(a[31]==1&&b[31]==0) begin
                r=1;
                negative=1;
                end
            if(a==b) zero=1;
            else zero=0;
        end
      else if(aluc[3]==1&&aluc[2]==0&&aluc[1]==1&&aluc[0]==0)
        begin
            if(a<b) begin
                r=1;
                carry=1;
            end
            else begin
                r=0;
                carry=0;
            end
            if(r[31]==1) negative=1;
            else negative=0;
            if(a==b) zero=1;
            else zero=0;
        end
      else if(aluc[3]==1&&aluc[2]==1&&aluc[1]==0&&aluc[0]==0)
        begin
//            r=b>>>a;
            r=b;
            case(a)
            0:r={r[31],r[31:0]};
            1:r={r[31],r[31:1]};
            2:r={{2{r[31]}},r[31:2]};
            3:r={{3{r[31]}},r[31:3]};
            4:r={{4{r[31]}},r[31:4]};
            5:r={{5{r[31]}},r[31:5]};
            6:r={{6{r[31]}},r[31:6]};  
            7:r={{7{r[31]}},r[31:7]};
            8:r={{8{r[31]}},r[31:8]};
            9:r={{9{r[31]}},r[31:9]};
            10:r={{10{r[31]}},r[31:10]};
            11:r={{11{r[31]}},r[31:11]}; 
            12:r={{12{r[31]}},r[31:12]};
            13:r={{13{r[31]}},r[31:13]};
            14:r={{14{r[31]}},r[31:14]};
            15:r={{15{r[31]}},r[31:15]};
            16:r={{16{r[31]}},r[31:16]}; 
            17:r={{17{r[31]}},r[31:17]};
            18:r={{18{r[31]}},r[31:18]};
            19:r={{19{r[31]}},r[31:19]};
            20:r={{20{r[31]}},r[31:20]};
            21:r={{21{r[31]}},r[31:21]}; 
            22:r={{22{r[31]}},r[31:22]};
            23:r={{23{r[31]}},r[31:23]};
            24:r={{24{r[31]}},r[31:24]};
            25:r={{25{r[31]}},r[31:25]};
            26:r={{26{r[31]}},r[31:26]}; 
            27:r={{27{r[31]}},r[31:27]};
            28:r={{28{r[31]}},r[31:28]};
            29:r={{29{r[31]}},r[31:29]};
            30:r={{30{r[31]}},r[31:30]};
            31:r={{31{r[31]}},r[31:31]};                                                                                  
            endcase
            carry=b[a-1];
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==1&&aluc[2]==1&&aluc[1]==1)
        begin
            r=b<<a;
            carry=b[31-a];
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
      else if(aluc[3]==1&&aluc[2]==1&&aluc[1]==0&&aluc[0]==1)
        begin
            r=b>>a;
            carry=b[a-1];
            if(r[31]==1) negative=1;
            else negative=0;
            if(r==0) zero=1;
            else zero=0;  
        end
    end
endmodule

通用寄存器模块

32位Mips架构CPU中包含32个通用寄存器

`timescale 1ns / 1ps
module RegFiles(
    input clk,
    input rst,
    input we,
    input [4:0] raddr1,
    input [4:0] raddr2,
    input [4:0] waddr,
    input [31:0] wdata,
    output [31:0] rdata1,
    output [31:0] rdata2
    );
    
    reg [31:0] array_reg [0:31];
    integer i;
    always@(posedge clk or posedge rst) begin
        if(rst) begin
            for(i=0;i<32;i=i+1)
                array_reg[i]<=32'b0;
        end
        else begin
            if(we&&waddr!=5'b0) 
                array_reg[waddr]<=wdata;
        end
    end
    
    assign rdata1=(raddr1==5'b0)?32'b0:array_reg[raddr1];
    assign rdata2=(raddr2==5'b0)?32'b0:array_reg[raddr2];
endmodule

RAM模块

为了简化,这个CPU把指令存储器和数据存储器分开了

`timescale 1ns / 1ps
module IMEM(
 //   input clk,
 //   input wena,
    input [10:0] addr,
//    input [31:0] data_in,
    output [31:0] data_out
    );
    reg [31:0] state [0:1024];
 //   wire [31:0] real_addr=(addr-32'h00400000)/4;
    initial begin
    $readmemh("E:/vivado_projects/CSCPU/31CPUtest/_1_addi.hex.txt",state);
    end
    
 /*  always @(posedge clk) begin
        if(wena) begin
            if(addr!=0) state[addr]<=data_in;
        end
    end*/
    
    assign data_out=state[addr];
endmodule

module DMEM(
    input clk,
    input cs,
    input we,
    input re,
    input [31:0] addr,
    input [31:0] data_in,
    output [31:0] data_out
    );
    
    reg [31:0] state [0:1024];
    wire [31:0] really_addr;
    assign really_addr=(addr-32'h10010000)/4;
    always @(negedge clk) begin
        if(we) begin
             state[really_addr]<=data_in;
        end
    end
    assign data_out=re?state[really_addr]:32'bz;
endmodule

PC寄存器模块

pc寄存器保存取指的地址

`timescale 1ns / 1ps
module PC_Reg(
    input clk,
    input rst,
    input ena,
    input [31:0] data_in,
    output [31:0] data_out,
    output [31:28] pc31_28
    );
    
    reg [31:0] data;
    
    always @(posedge clk or posedge rst) begin
        if(rst) data<=32'h00400000;
        else begin
            if(ena) data<=data_in;
        end
    end
    assign data_out=data;
    assign pc31_28=data[31:28];
endmodule

ADD

`timescale 1ns / 1ps

module ADDU(
    input [31:0] a,
    input [31:0] b,
    output [31:0] c
    );
    assign c=a+b;
endmodule

module ADD(
    input [31:0] a,
    input [31:0] b,
    output [31:0] c
);
       reg [32:0] result;
       wire signed [31:0] sa=a,sb=b;
       
       always @(*) begin
        result=sa+sb;
       end
       assign c=result[31:0];
endmodule

MUX数据选择器

`timescale 1ns / 1ps
module MUX(
    input m,
    input [31:0] data_in1,
    input [31:0] data_in2,
    output [31:0] data_out
    );
    assign data_out=(m==0)?data_in1:data_in2;
endmodule

module MUXS(
    input [1:0] m,
    input [31:0] data_in1,
    input [31:0] data_in2,
    input [31:0] data_in3,
    output [31:0] data_out
    );
    reg [31:0] out;
    always@(*)begin
        case(m)
            2'b00:out<=data_in1;
            2'b01:out<=data_in2;
            2'b11:out<=data_in3;
            default: out<=32'b0;
        endcase
    end
    assign data_out=out;
endmodule

数据扩展器

`timescale 1ns / 1ps
module Ext_imm5(
    input [4:0] idata,
    output [31:0] odata,
    input ca
    );
    assign odata=(ca==0)?{27'b0,idata}:{{27{idata[4]}},idata};
endmodule

module Ext_imm16(
    input [15:0] idata,
    output [31:0] odata,
    input ca
    );
    assign odata=(ca==0)?{16'b0,idata}:{{16{idata[15]}},idata};
endmodule

module Ext_imm18(
    input [15:0] idata,
    output [31:0] odata,
    input ca
    );
    assign odata=(ca==0)?{14'b0,idata,2'b0}:{{14{idata[15]}},idata,2'b0};
endmodule

顶层模块设计

顶层模块将CPU与存储器、外部设备连接

`timescale 1ns / 1ps

module sccomp_dataflow(
input clk_in,
input reset,
output [31:0] inst,
output [31:0] pc,
output [31:0] addr
    ); 
	 
wire [31:0]rdata;
wire [31:0]wdata;
//wire [31:0]inst,pc,addr;
wire [31:0]data_fmem;
wire [31:0]ip_in;
wire IM_R;
wire DM_CS;
wire DM_W;
wire DM_R;
wire [5:0] op_out;
wire Z;
assign ip_in = pc-32'h00400000;

cpu sccpu(
    .clk(clk_in),
    .rst(reset),
    .inst(inst),
    .rdata(rdata),
    .pcdata(pc),
    .addr(addr),
    .wdata(wdata),
    .im_r(IM_R),
    .dm_cs(DM_CS),
    .dm_r(DM_R),
    .dm_w(DM_W),
    .op_out(op_out),
    .Z(z)
);
    dist_mem_gen_0 imem(
    .a(ip_in[12:2]),
    .spo(inst)
    );
DMEM dmem(
    .clk(clk_in),
    .cs(DM_CS),
    .we(DM_W),
    .re(DM_R),
    .addr(addr),
    .data_in(wdata),
    .data_out(rdata)
);
endmodule

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值