31条指令单周期cpu设计(Verilog)-(九)上代码→基本模块

不再赘述,直接上

mux

`timescale 1ns / 1ns
module mux(
    input [31:0] a,
    input [31:0] b,
    input choose,
    output reg [31:0] z
    );
    always @(*)
    begin
    case(choose)
        1'b1:z <= b;
        1'b0:z <= a;
   endcase
   end
endmodule

mux5

`timescale 1ns / 1ns
module mux5(
    input [4:0] a,
    input [4:0] b,
    input [1:0] choose,
    output [4:0] z
    );
    reg [4:0] t_z;
    always @(*)
    begin
    case(choose)
        2'b01:t_z <= b;
        2'b00:t_z <= a;
        2'b10:t_z <= 5'b11111;
        2'b11:t_z <= 5'b11111;
        default:t_z <= 5'bz;
    endcase
    end
    assign z = t_z;
endmodule

extend5

`timescale 1ns / 1ns
module extend5 #(parameter WIDTH = 5)(
    input [WIDTH - 1:0] a,
    output [31:0] b
    );
    assign b = {{(32 - WIDTH){1'b0}},a};
endmodule

extend16

`timescale 1ns / 1ns
module extend16 #(parameter WIDTH = 16)(
    input [WIDTH - 1:0] a,
    input sext,             //1表示有符号
    output [31:0] b
    );
    assign b = sext ? {{(32 - WIDTH){a[WIDTH - 1]}},a} : {{(32 - WIDTH){1'b0}},a};
endmodule

extend18

`timescale 1ns / 1ns
module extend18 (
    input [15:0] a,
    output [31:0] b
    );
    assign b = {{(32 - 18){a[15]}},a,2'b00};
endmodule

add

`timescale 1ns / 1ns
module add(
    input [31:0] a,
    input [31:0] b,
    output [31:0] r,
    output overflow
    );
    assign r=a+b;
    assign overflow=(a[31]==b[31]&&a[31]!=r[31])?1:0;
endmodule

add8(是+4没错

`timescale 1ns / 1ns
module add8(
    input [31:0] a,
    output [31:0] r
    );
    assign r=a+4;
endmodule

npc

`timescale 1ns / 1ns
module npc(
    input [31:0] a,
    input rst,
    output [31:0] r
    );
    assign r = rst ? a : a+4;
endmodule

pcreg(可以改进)

`timescale 1ns / 1ns
module pcreg(
    input clk,  //1 位输入,寄存器时钟信号,下降沿时为 PC 寄存器赋值
    input rst,  //1 位输入,异步重置信号,高电平时将 PC 寄存器清零
                //注:当 ena 信号无效时,rst 也可以重置寄存器
    input ena,  //1 位输入,有效信号高电平时 PC 寄存器读入 data_in的值,否则保持原有输出
    input [31:0] data_in,       //32 位输入,输入数据将被存入寄存器内部
    output [31:0] data_out  //32 位输出,工作时始终输出 PC寄存器内部存储的值
    );
    D_FF D0 (clk,data_in[0],ena,rst,data_out[0]);
    D_FF D1 (clk,data_in[1],ena,rst,data_out[1]);
    D_FF D2 (clk,data_in[2],ena,rst,data_out[2]);
    D_FF D3 (clk,data_in[3],ena,rst,data_out[3]);
    D_FF D4 (clk,data_in[4],ena,rst,data_out[4]);
    D_FF D5 (clk,data_in[5],ena,rst,data_out[5]);
    D_FF D6 (clk,data_in[6],ena,rst,data_out[6]);
    D_FF D7 (clk,data_in[7],ena,rst,data_out[7]);
    D_FF D8 (clk,data_in[8],ena,rst,data_out[8]);
    D_FF D9 (clk,data_in[9],ena,rst,data_out[9]);
    D_FF D10 (clk,data_in[10],ena,rst,data_out[10]);
    D_FF D11 (clk,data_in[11],ena,rst,data_out[11]);
    D_FF D12 (clk,data_in[12],ena,rst,data_out[12]);
    D_FF D13 (clk,data_in[13],ena,rst,data_out[13]);
    D_FF D14 (clk,data_in[14],ena,rst,data_out[14]);
    D_FF D15 (clk,data_in[15],ena,rst,data_out[15]);
    D_FF D16 (clk,data_in[16],ena,rst,data_out[16]);
    D_FF D17 (clk,data_in[17],ena,rst,data_out[17]);
    D_FF D18 (clk,data_in[18],ena,rst,data_out[18]);
    D_FF D19 (clk,data_in[19],ena,rst,data_out[19]);
    D_FF D20 (clk,data_in[20],ena,rst,data_out[20]);
    D_FF D21 (clk,data_in[21],ena,rst,data_out[21]);
    D_FF1 D22 (clk,data_in[22],ena,rst,data_out[22]);     //以00400000为基地址
    //D_FF D22 (clk,data_in[22],ena,rst,data_out[22]);        //以00000000为基地址
    D_FF D23 (clk,data_in[23],ena,rst,data_out[23]);
    D_FF D24 (clk,data_in[24],ena,rst,data_out[24]);
    D_FF D25 (clk,data_in[25],ena,rst,data_out[25]);
    D_FF D26 (clk,data_in[26],ena,rst,data_out[26]);
    D_FF D27 (clk,data_in[27],ena,rst,data_out[27]);
    D_FF D28 (clk,data_in[28],ena,rst,data_out[28]);
    D_FF D29 (clk,data_in[29],ena,rst,data_out[29]);
    D_FF D30 (clk,data_in[30],ena,rst,data_out[30]);
    D_FF D31 (clk,data_in[31],ena,rst,data_out[31]);   
endmodule

module D_FF1(
    input CLK,      //时钟信号,下降沿有效
    input D,        //输入信号 D
    input ENA,
    input RST_n,    //复位信号,高电平有效
    output reg Q1  //输出信号 Q
    );
    
    always @(posedge RST_n or posedge CLK) 
    begin
      if(RST_n==1)
        Q1 <= 1;
      else
        begin
        if(ENA==1)
          Q1 <= D;
        end
    end
endmodule

 

alu

`timescale 1ns / 1ns
module alu(
    input [31:0] a,        //OP1
    input [31:0] b,        //OP2
    input [3:0] aluc,    //controller
    output [31:0] r,    //result
    output zero,
    output carry,
    output negative,
    output overflow);
        
    parameter Addu   =    4'b0000;    //r=a+b unsigned
    parameter Add    =    4'b0010;    //r=a+b signed
    parameter Subu   =    4'b0001;    //r=a-b unsigned
    parameter Sub    =    4'b0011;    //r=a-b signed
    parameter And    =    4'b0100;    //r=a&b
    parameter Or     =    4'b0101;    //r=a|b
    parameter Xor    =    4'b0110;    //r=a^b
    parameter Nor    =    4'b0111;    //r=~(a|b)
    parameter Lui1   =    4'b1000;    //r={b[15:0],16'b0}
    parameter Lui2   =    4'b1001;    //r={b[15:0],16'b0}
    parameter Slt    =    4'b1011;    //r=(a-b<0)?1:0 signed
    parameter Sltu   =    4'b1010;    //r=(a-b<0)?1:0 unsigned
    parameter Sra    =    4'b1100;    //r=b>>>a 
    parameter Sll    =    4'b1110;    //r=b<<a
    parameter Srl    =    4'b1101;    //r=b>>a
    parameter Slr    =    4'b1111;    //r=b<<a
    
    parameter bits=31;
    parameter ENABLE=1,DISABLE=0;
    
    reg signed [32:0] result;
    reg [33:0] sresult;
    wire signed [31:0] sa=a,sb=b;
  
    always@(*)begin
        case(aluc)
            Addu: begin
                result=a+b;
                sresult={sa[31],sa}+{sb[31],sb};
            end
            Subu: begin
                result=a-b;
                sresult={sa[31],sa}-{sb[31],sb};
            end
            Add: begin
                result=sa+sb;
            end
            Sub: begin
                result=sa-sb;
            end
            Sra: begin
                if(a==0) {result[31:0],result[32]}={b,1'b0};
                else {result[31:0],result[32]}=sb>>>(a-1);
            end
            Srl: begin
                if(a==0) {result[31:0],result[32]}={b,1'b0};
                else {result[31:0],result[32]}=b>>(a-1);
            end
            Sll,Slr: begin
                result=b<<a;
            end
            And: begin
                result=a&b;
            end
            Or: begin
                result=a|b;
            end
            Xor: begin
                result=a^b;
            end
            Nor: begin
                result=~(a|b);
            end
            Sltu: begin
                result=a<b?1:0;
            end
            Slt: begin
                result=sa<sb?1:0;
            end
            Lui1,Lui2: result = {b[15:0], 16'b0};
            default:
                result=a+b;
        endcase
    end
    
    assign r=result[31:0];
    assign carry = (aluc==Addu|aluc==Subu|aluc==Sltu|aluc==Sra|aluc==Srl|aluc==Sll)?result[32]:1'bz; 
    assign zero=(r==32'b0)?1:0;
    assign negative=result[31];
    assign overflow=(aluc==Add|aluc==Sub)?(sresult[32]^sresult[33]):1'bz;
endmodule

regfile(可以改进)

`timescale 1ns / 1ns
module regfile(
    input clk, //寄存器组时钟信号,下降沿写入数据
    input rst, //reset 信号,异步复位,高电平时全部寄存器置零
    input we, //寄存器读写有效信号,高电平时允许寄存器写入数据,低电平时允许寄存器读出数据
    input ov,
    input [4:0] raddr1, //所需读取的寄存器的地址
    input [4:0] raddr2, //所需读取的寄存器的地址
    input [4:0] waddr, //写寄存器的地址
    input [31:0] wdata, //写寄存器数据,数据在 clk 下降沿时被写入
    output [31:0] rdata1, //raddr1 所对应寄存器的输出数据
    output [31:0] rdata2 //raddr2 所对应寄存器的输出数据
    );
    wire [31:0] switch;
    wire [31:0] array_reg [31:0];
    reg c_o;
    always@(ov)
    begin
    case(ov)
    1'bz:c_o = 1;
    1'b1:c_o = 0;
    1'b0:c_o = 1;
    default:c_o=1;
    endcase
    end
    Decoder dec (waddr,we&c_o,switch);
    assign array_reg[0] = 0;
    Pcreg Reg2 (clk,rst,switch[1],wdata,array_reg[1]);
    Pcreg Reg3 (clk,rst,switch[2],wdata,array_reg[2]);
    Pcreg Reg4 (clk,rst,switch[3],wdata,array_reg[3]);
    Pcreg Reg5 (clk,rst,switch[4],wdata,array_reg[4]);
    Pcreg Reg6 (clk,rst,switch[5],wdata,array_reg[5]);
    Pcreg Reg7 (clk,rst,switch[6],wdata,array_reg[6]);
    Pcreg Reg8 (clk,rst,switch[7],wdata,array_reg[7]);
    Pcreg Reg9 (clk,rst,switch[8],wdata,array_reg[8]);
    Pcreg Reg10 (clk,rst,switch[9],wdata,array_reg[9]);
    Pcreg Reg11 (clk,rst,switch[10],wdata,array_reg[10]);
    Pcreg Reg12 (clk,rst,switch[11],wdata,array_reg[11]);
    Pcreg Reg13 (clk,rst,switch[12],wdata,array_reg[12]);
    Pcreg Reg14 (clk,rst,switch[13],wdata,array_reg[13]);
    Pcreg Reg15 (clk,rst,switch[14],wdata,array_reg[14]);
    Pcreg Reg16 (clk,rst,switch[15],wdata,array_reg[15]);
    Pcreg Reg17 (clk,rst,switch[16],wdata,array_reg[16]);
    Pcreg Reg18 (clk,rst,switch[17],wdata,array_reg[17]);
    Pcreg Reg19 (clk,rst,switch[18],wdata,array_reg[18]);
    Pcreg Reg20 (clk,rst,switch[19],wdata,array_reg[19]);
    Pcreg Reg21 (clk,rst,switch[20],wdata,array_reg[20]);
    Pcreg Reg22 (clk,rst,switch[21],wdata,array_reg[21]);
    Pcreg Reg23 (clk,rst,switch[22],wdata,array_reg[22]);
    Pcreg Reg24 (clk,rst,switch[23],wdata,array_reg[23]);
    Pcreg Reg25 (clk,rst,switch[24],wdata,array_reg[24]);
    Pcreg Reg26 (clk,rst,switch[25],wdata,array_reg[25]);
    Pcreg Reg27 (clk,rst,switch[26],wdata,array_reg[26]);
    Pcreg Reg28 (clk,rst,switch[27],wdata,array_reg[27]);
    Pcreg Reg29 (clk,rst,switch[28],wdata,array_reg[28]);
    Pcreg Reg30 (clk,rst,switch[29],wdata,array_reg[29]);
    Pcreg Reg31 (clk,rst,switch[30],wdata,array_reg[30]);
    Pcreg Reg32 (clk,rst,switch[31],wdata,array_reg[31]);
    assign rdata1 = array_reg[raddr1];
    assign rdata2 = array_reg[raddr2];
endmodule

module Decoder(
    input [4:0] iData,      
    input  iEna,            
    output [31:0] oData      
    );        
    assign oData=(iEna==1)?(32'b00000000000000000000000000000001<<iData):32'bx;
endmodule

module Pcreg(
    input clk,  //1 位输入,寄存器时钟信号,下降沿时为 PC 寄存器赋值
    input rst,  //1 位输入,异步重置信号,高电平时将 PC 寄存器清零
                //注:当 ena 信号无效时,rst 也可以重置寄存器
    input ena,  //1 位输入,有效信号高电平时 PC 寄存器读入 data_in的值,否则保持原有输出
    input [31:0] data_in,       //32 位输入,输入数据将被存入寄存器内部
    output [31:0] data_out  //32 位输出,工作时始终输出 PC寄存器内部存储的值
    );
    
    D_FF d0 (clk,data_in[0],ena,rst,data_out[0]);
    D_FF d1 (clk,data_in[1],ena,rst,data_out[1]);
    D_FF d2 (clk,data_in[2],ena,rst,data_out[2]);
    D_FF d3 (clk,data_in[3],ena,rst,data_out[3]);
    D_FF d4 (clk,data_in[4],ena,rst,data_out[4]);
    D_FF d5 (clk,data_in[5],ena,rst,data_out[5]);
    D_FF d6 (clk,data_in[6],ena,rst,data_out[6]);
    D_FF d7 (clk,data_in[7],ena,rst,data_out[7]);
    D_FF d8 (clk,data_in[8],ena,rst,data_out[8]);
    D_FF d9 (clk,data_in[9],ena,rst,data_out[9]);
    D_FF d10 (clk,data_in[10],ena,rst,data_out[10]);
    D_FF d11 (clk,data_in[11],ena,rst,data_out[11]);
    D_FF d12 (clk,data_in[12],ena,rst,data_out[12]);
    D_FF d13 (clk,data_in[13],ena,rst,data_out[13]);
    D_FF d14 (clk,data_in[14],ena,rst,data_out[14]);
    D_FF d15 (clk,data_in[15],ena,rst,data_out[15]);
    D_FF d16 (clk,data_in[16],ena,rst,data_out[16]);
    D_FF d17 (clk,data_in[17],ena,rst,data_out[17]);
    D_FF d18 (clk,data_in[18],ena,rst,data_out[18]);
    D_FF d19 (clk,data_in[19],ena,rst,data_out[19]);
    D_FF d20 (clk,data_in[20],ena,rst,data_out[20]);
    D_FF d21 (clk,data_in[21],ena,rst,data_out[21]);
    D_FF d22 (clk,data_in[22],ena,rst,data_out[22]);
    D_FF d23 (clk,data_in[23],ena,rst,data_out[23]);
    D_FF d24 (clk,data_in[24],ena,rst,data_out[24]);
    D_FF d25 (clk,data_in[25],ena,rst,data_out[25]);
    D_FF d26 (clk,data_in[26],ena,rst,data_out[26]);
    D_FF d27 (clk,data_in[27],ena,rst,data_out[27]);
    D_FF d28 (clk,data_in[28],ena,rst,data_out[28]);
    D_FF d29 (clk,data_in[29],ena,rst,data_out[29]);
    D_FF d30 (clk,data_in[30],ena,rst,data_out[30]);
    D_FF d31 (clk,data_in[31],ena,rst,data_out[31]);   
endmodule

module D_FF(
    input CLK,      //时钟信号,下降沿有效
    input D,        //输入信号 D
    input ENA,
    input RST_n,    //复位信号,高电平有效
    output reg Q1  //输出信号 Q1
    );
    
    // 2020/03/29 有小伙伴指出这里可能有问题, negedge CLK, 请以仿真结果为准(博主无法进行仿真了)
    always @(posedge RST_n or posedge CLK)
    begin
      if(RST_n==1)
        Q1 = 0;
      else
      begin
      if(ENA==1)
        Q1 = D;
      end
    end
endmodule

II

`timescale 1ns / 1ns
module II(
    input [3:0] a,
    input [25:0] b,
    output [31:0] r
    );
    assign r = {a, b<<2};
endmodule

 

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值