用verilog写一个最简单的CPU

//最简单计算机核设计 2009-4-29(可下载到开发板验证)
//可以用QuartusII编译下载 
//解释权姜咏江 Email:[email protected],
//参考书:姜咏江.PMC计算机设计与应用.清华大学出版社.2008-5

//基本输入时钟clock
//复位控制:reset_n,低电位有效
//基本输出:o
//程序存储器iram,16位,高5位是类指令代码,用imem16.mif初始化
//数据存储器dram,16位,不用数据文件初始化
//用lpm存储器地址信号要稳定1拍,才可以读写数据

//指令格式:高5位指令代码,11位地址码,16位立即数(分高低8位)

module test
    (
        clock,
        reset_n,
        o,
        //调试输出(可以不要):
        opc,
        omar,
        ojp,
        oqw,
        olda,
        oadd,
        oout
    );

    input    clock;
    input    reset_n;
    output [15:0]    o;
   
    output [15:0]    oqw;
    output [10:0]    opc,omar;
    output [2:0]    ojp;
    output            olda,oadd,oout;
   
    wire dwren;
    wire [15:0] q_w;
    wire [15:0] q_data;
    reg     [15:0]    b,a,ir,da,oo,ddata;
    reg  [10:0]    pc,mar;
    reg  [2:0]    jp;        //节拍
    reg            dwrit;    //写控制
//指令:
    reg         lda,    //取数:从数据单元取数到da
                add,    //加:da与数据单元相加,结果放入da
                out,    //输出:将数据单元内容输出到输出寄存器
                sdal,    //低8位立即数:将8位立即数扩充为16位送da
                sdah,    //高8位立即数:将8位立即数作为高8位,与原da低8位连接成16位放在da中
                str;    //da送数据存储单元:
//仿真信号输出:
    assign o    = oo;
    assign opc  = pc;
    assign omar = mar;
    assign ojp    = jp;
    assign oqw    = q_w;
    assign olda=lda;
    assign oadd=add;
    assign oout=out;
    assign dwren = dwrit;
//指令存储器:    
    lpm_rom iram(.address(pc),.inclock(clock),.q(q_w));  //程序存储器
    defparam iram.lpm_width = 16;
    defparam iram.lpm_widthad = 11;
    defparam iram.lpm_outdata = "UNREGISTERED";
    defparam iram.lpm_indata = "REGISTERED";
    defparam iram.lpm_address_control = "REGISTERED";
    defparam iram.lpm_file = "imem16.mif";  //初始化文件,放置程序
//数据存储器:   
    lpm_ram_dq dram(.data(ddata),.address(mar),.we(dwren),.inclock(clock),.q(q_data)); //数据存储器
    defparam dram.lpm_width = 16;
    defparam dram.lpm_widthad = 11;
    defparam dram.lpm_outdata = "UNREGISTERED";
    defparam dram.lpm_indata = "REGISTERED";
    defparam dram.lpm_address_control = "REGISTERED";
   
        always @(posedge clock or negedge reset_n)
begin
    if (!reset_n)
    begin
        pc  <= 0;
        lda <= 0;  
        add <= 0;  
        out <= 0;   
        sdal <= 0;   
        sdah <= 0;   
        str <= 0;   
        jp<=0;
    end
    else
    begin
        jp<=jp+1;
        case (jp)
        0:    begin
            end
        1:    begin
                case (q_w[15:11])
                5'b00001:    lda <= 1;    //lda:00001
                5'b00010:    add <= 1;    //add:00010
                5'b00011:   out <= 1;    //out:00011
                5'b00100:   sdal <= 1;    //低8位,扩充有符号16位
                5'b00101:   sdah <= 1;    //高8位,与前面低8位输入合成16位
                5'b00110:   str <= 1;    //da送数据单元
                endcase
            end
        2:    begin
            if (lda || add || out || str)
                mar<=q_w[10:0];
            end
        3:    pc<=pc+1;
        4:    begin
            if (lda)
                begin
                    da<=q_data;
                    jp <= 0;
                    lda<= 0;
                end
            else
            if (add)
                begin
                    b<=q_data;
                    a<=da;
                end
            else
            if (out)
                    begin
                        oo <= q_data;
                        jp <= 0;
                        out<= 0;
                     end
            else
            if (sdal)
                    begin
                        da <= {{8{q_w[7]}},q_w[7:0]};        //扩充16位有符号数
                        sdal<= 0;
                    end
            else
            if (sdah) 
                    begin
                        da[15:0] <= {q_w[7:0],da[7:0]};
                        sdah <= 0;
                    end
            else
            if (str)
                    begin
                        ddata <= da;
                        dwrit <= 1;
                    end      
            end
           
        5:    begin
                if (add)
                    begin
                        da<=a+b;
                        jp <= 0;
                        add<= 0;
                     end
                else
                if (str)
                begin
                    str <= 0;
                    dwrit <= 0;
                end
            end
       
        endcase
    end
end

        endmodule
 
  仿真实例  ///
//    汇编            编译               //
//    sdal    5            2005         //
//    sdah    6            2806         //   
//    str    10            300a         //
//    sdal    3            2003         //
//    add    10            100a         //
//    str    15            300f         //
//    out    15            180f         //
//                                      //
//将编译的16进制数写入imem16.mif ,然后再编译一次        //   
//                                      //
///  16进制输出:0608  /

你可能感兴趣的:(CPU设计,CPU设计)