合工大计组实验八 单周期CPU中指令控制器的设计与仿真

目录

实验目标及任务

实验内容与结果记录 

 本次实验中需要注意的部分:

实验目标及任务

实验目的:

1、深入了解单周期CPU中指令控制器的结构和工作原理。

2、学习使用Verilog HDL设计实现单周期CPU中指令控制器。

实验任务:

1、设计和实现单周期CPU中指令控制器的结构并且进行功能仿真。

实验内容与结果记录 

源代码:

//根据机器码操作,控制各个信号
module SCPU_ctrl(
    input[5:0] OPcode,    //OPcode 
    input[5:0] func,      //function 
    output wire RegDst,
    output wire ALUSrc_B, 
    output wire MemtoReg, 
    output wire Jump, 
    output wire Branch, 
    output wire RegWrite, 
    output wire[2:0] ALU_Control, 
    output wire MemRead,
    output wire MemWrite
    );
    wire R_format,LW,SW,Beq;
    assign R_format=~(OPcode[5] | OPcode[4] | OPcode[3] | OPcode[2] | OPcode[1] | OPcode[0]);//000000
    assign LW=(OPcode[5] & ~OPcode[3] & ~OPcode[2] & OPcode[1] & OPcode[0]);//1x0011
    assign SW=(OPcode[5] & OPcode[3] & ~OPcode[2] & OPcode[1] & OPcode[0]);//1x1011
    assign Beq=(~OPcode[5] & ~OPcode[3] & OPcode[2] & ~OPcode[1] & ~OPcode[0]);//0x0100
    
    assign Branch=Beq;
    assign RegWrite=( R_format | LW );
    assign RegDst=R_format;
    assign MemtoReg=LW;
    assign ALUSrc_B=( SW | LW );
    assign MemWrite=SW;
    assign Jump=(~OPcode[5] & ~OPcode[3] & ~OPcode[2] & OPcode[1] & ~OPcode[0]);//0x0010
    assign MemRead=LW;
    
    wire ALUop0,ALUop1;//控制器输入操作码
    buf b0(ALUop0,Beq);
    buf b1(ALUop1,R_format);
    
    wire A1,AB1,O1,N_FUNC1;
    and AND1(A1 , ALUop1 , func[1]);
    not N1( N_FUNC1, func[1] );
    and AND2B1( AB1, func[0], N_FUNC1 );
    or OR1( O1, AB1, func[3] );
    or OR2( ALU_Control[2], ALUop0, A1 );
    nand NAND2( ALU_Control[1], ALUop1, func[2] );
    and AND2( ALU_Control[0], ALUop1, O1 );

endmodule



//读取文件,获取机器码
module instruction_memory (
    input [31:0] address,
    output reg [31:0] instruction//作用是提供opcode和func
    );
    reg [31:0] memoryy [255:0]; // 假设指令存储器大小为256条指令
    initial begin
        $readmemh("D:/Vivado projects/EXP8_0/instruction.txt", memoryy);
        instruction =1;
    end

    always @(address) begin
        instruction = memoryy[address[31:2]]; // 按字对齐
    end
endmodule




//总调用
module top (
    input [8:0] addresssw,//开关信号控制address
    /*
    input [5:0] opcode,//这两个后面改成addresssw,调用instructionmemory来赋值opcode,调用scpu
    input [5:0] func,
    */
    output [10:0] leds
    );
    reg [31:0] address;
    wire [31:0] instruction;
    always @(*)begin
        case(addresssw)
            9'b100000000: address=32'h00;
            9'b010000000: address=32'h04;
            9'b001000000: address=32'h08;
            9'b000100000: address=32'h0c;
            9'b000010000: address=32'h10;
            9'b000001000: address=32'h14;
            9'b000000100: address=32'h18;
            9'b000000010: address=32'h1c;
            9'b000000001: address=32'h20;
    endcase
    end
    instruction_memory im(
        .address(address),
        .instruction(instruction)
    );

    wire RegDst, ALUSrc_B, MemtoReg, Jump, Branch, RegWrite, MemRead, MemWrite;
    wire [2:0] ALU_Control;
    
    SCPU_ctrl ctrl (
        .OPcode(instruction[31:26]),
        .func(instruction[5:0]),
        .RegDst(RegDst),
        .ALUSrc_B(ALUSrc_B),
        .MemtoReg(MemtoReg),
        .Jump(Jump),
        .Branch(Branch),
        .RegWrite(RegWrite),
        .ALU_Control(ALU_Control),
        .MemRead(MemRead),
        .MemWrite(MemWrite)
    );
    
    assign leds[0] = Jump;
    assign leds[1] = Branch;
    assign leds[2] = MemWrite;
    assign leds[3] = MemRead;
    assign leds[4] = RegWrite;
    assign leds[5] = MemtoReg;
    assign leds[6] = ALUSrc_B;
    assign leds[7] = RegDst;
    assign leds[8] = ALU_Control[0];
    assign leds[9] = ALU_Control[1];
    assign leds[10] = ALU_Control[2];
    // 其余的LED信号可以根据需要连接
endmodule

激励文件:

module testbench;

    // Inputs
    reg [8:0] addresssw;
    wire [10:0] leds;


    // Instantiate the top module
    top uut_top (
        .addresssw(addresssw),
        .leds(leds)
    );

    initial begin
        // Initialize Inputs
        addresssw=9'b100000000;
        #10;
        addresssw= 9'b010000000;
        #10;
        addresssw=9'b001000000;
        #10;
        addresssw=9'b000100000;
        #10;
        $finish;
    end

endmodule

引脚约束文件:

set_property PACKAGE_PIN P5 [get_ports {addresssw[8]}]
set_property PACKAGE_PIN P4 [get_ports {addresssw[7]}]  
set_property PACKAGE_PIN P3 [get_ports {addresssw[6]}] 
set_property PACKAGE_PIN P2 [get_ports {addresssw[5]}] 
set_property PACKAGE_PIN R2 [get_ports {addresssw[4]}]  
set_property PACKAGE_PIN M4 [get_ports {addresssw[3]}] 
set_property PACKAGE_PIN N4 [get_ports {addresssw[2]}] 
set_property PACKAGE_PIN R1 [get_ports {addresssw[1]}] 
set_property PACKAGE_PIN U3 [get_ports {addresssw[0]}] 

set_property PACKAGE_PIN F6 [get_ports {leds[10]}]
set_property PACKAGE_PIN G4 [get_ports {leds[9]}]
set_property PACKAGE_PIN G3 [get_ports {leds[8]}]
set_property PACKAGE_PIN J4 [get_ports {leds[7]}]
set_property PACKAGE_PIN H4 [get_ports {leds[6]}]
set_property PACKAGE_PIN J3 [get_ports {leds[5]}]
set_property PACKAGE_PIN J2 [get_ports {leds[4]}]
set_property PACKAGE_PIN K2 [get_ports {leds[3]}]
set_property PACKAGE_PIN K1 [get_ports {leds[2]}]
set_property PACKAGE_PIN H6 [get_ports {leds[1]}]
set_property PACKAGE_PIN H5 [get_ports {leds[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {addresssw[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {leds[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds[0]}]

模拟仿真图像:

下载到开发板上的图片结果:

图一
图二
图三

 本次实验中需要注意的部分:

实验需要了解verilog的文件操作,学习readmemh的使用方法。

会注意到“文件内容只应该有空白符(或换行、空格符)、二进制或十六进制数据,注释用"//"进行标注,数据间建议用换行符区分”,这是我重写instruction.txt机器码文件的原因;我读出文件内容使用的是绝对路径(在“源代码”第76行),使用时要注意修改。

地址对应的指令则需要的instruction.txt文件我自己重写后内容如下:

00000020     //add 000000  xx xxxx xxxx xxxx xxxx xx   100000   该文本中x全当0处理

00000022     //sub 000000  xx xxxx xxxx xxxx xxxx xx   100010

00000024     //and 000000  xx xxxx xxxx xxxx xxxx xx   100100

00000025     //or 000000  xx xxxx xxxx xxxx xxxx xx   100101

0000002a     //sll 000000  xx xxxx xxxx xxxx xxxx xx   101010

8c000000     //LW 100011  xx xxxx xxxx xxxx xxxx xx   xxxxxx

ac000000     //SW 101011  xx xxxx xxxx xxxx xxxx xx   xxxxxx

10000000     //BEQ 000100  xx xxxx xxxx xxxx xxxx xx   xxxxxx

08000000     //JUMP 000010  xx xxxx xxxx xxxx xxxx xx   xxxxxx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值