西南交通大学 计算机组成原理实验课程设计

 代码部分:

module CPU(  
input clk,              //时钟  
input reset,            //复位  
input [7:0]M_data_in,  
output reg Wirte_read,  
output [11:0]M_address,  
output [7:0]M_data_out,  
output reg overflow  
);  
//通用寄存器组  
reg[7:0]R0;  
reg[7:0]R1;  
reg[7:0]R2;  
reg[7:0]R3;  
reg[11:0]PC;    //程序计数器  
reg[15:0]IR;    //指令寄存器  
reg [7:0]Acc;   //累加寄存器/临时寄存器  
reg [8:0]temp;  //加减运算扩充符号位后的临时寄存器  
reg [11:0]MAR;  //内存地址寄存器  
reg [7:0]MDR;   //内存数据寄存器  
assign  M_address = MAR;  
assign  M_data_out = MDR;  
//状态  
localparam st_0  =  3'b000;  
localparam st_1  =  3'b001;  
localparam st_2  =  3'b010;  
localparam st_3  =  3'b011;  
localparam st_4  =  3'b100;  
reg [2:0]status /*synthesis preserve*/;  
//指令助记符  
parameter Idle = 4'b0000;  
parameter Load = 4'b0001;  
parameter Move = 4'b0010;  
parameter Add  = 4'b0011;  
parameter Sub  = 4'b0100;  
parameter AND  = 4'b0101;  
parameter OR   = 4'b0110;  
parameter XOR  = 4'b0111;  
parameter Shr  = 4'b1000;  
parameter Shl  = 4'b1001;  
parameter Swap = 4'b1010;  
parameter Jmp  = 4'b1011;  
parameter Jz   = 4'b1100;  
parameter Read = 4'b1101;  
parameter Write = 4'b1110;  
parameter Stop = 4'b1111;  
  
always @(*)   
begin  
    if(status == st_3 && reset == 1'b1 && IR[15:12] == Write)  
        Wirte_read = 1'b1;  
    else  
        Wirte_read = 1'b0;  
    if(status == st_1 && reset == 1'b1 && (IR[15:12]==Add || IR[15:12]==Sub)) 
        if(temp[8]^temp[7])   
            overflow = 1'b1;  
        else  
            overflow = 1'b0;  
    else    overflow = 1'b0;  
end  

 always @(posedge clk,negedge reset)  
begin  
    if(reset == 1'b0)  
        begin  
            R0 = 8'b0000_0000;  
            R1 = 8'b0000_0000;  
            R2 = 8'b0000_0000;  
            R3 = 8'b0000_0000;  
            PC = 8'b0000_0000;  
            IR = 16'h0000;  
            MDR = 8'b0000_0000;  
        end  
    else  
        case(status)  
            st_0:  
                begin  
                    IR[15:8] = M_data_in;  
                    IR[7:0]  = 8'b0000_0000;  
                    if(IR[15:12] != 4'b1111)  
                    PC = PC + 1'b1;  
                end  
            st_1:  
                begin  
                    case(IR[15:12])  
                        Idle:begin  end  
                        Load:begin  
                            R0 = IR[11:8];  
                            end  
                        Move:begin  
                            case(IR[11:10])  
                                2'b00:R0 = Acc;  
                                2'b01:R1 = Acc;  
                                2'b10:R2 = Acc;  
                                2'b11:R3 = Acc;  
                            endcase  
                            end  
                        Add:begin  
                            case(IR[11:10])  
                                2'b00:begin  
                                    temp = {R0[7],R0}+{Acc[7],Acc};  
                                    R0 = temp[7:0];  
                                    end  
                                2'b01:begin  
                                    temp = {R1[7],R1}+{Acc[7],Acc};  
                                    R1 = temp[7:0];  
                                    end  
                                2'b10:begin  
                                    temp = {R2[7],R2}+{Acc[7],Acc};  
                                    R2 = temp[7:0];  
                                    end  
                                2'b11:begin  
                                    temp = {R3[7],R3}+{Acc[7],Acc};  
                                    R3 = temp[7:0];  
                                    end   
                            endcase  
                            end  
                        Sub:begin  
//先求-Acc的补码,将补码减法变为补码加法 (x-y)补=x补+(-y)  
//对于这里没有直接将-Acc的补码存在Acc寄存器里的解释:  
//因为在时钟下降沿那个always块里有Acc的赋值,同一个寄存器的赋值不能出现在多个always语句里,会产生冲突  
//虽然一个时钟上升沿一个时钟下降沿不会产生冲突,但是编译时仍会报错  
//这也是为什么寄存器的清零一部分放在时钟上升沿时,一部分放在时钟下降沿时  
                            temp[7:0] = ~Acc;  
                            temp[7:0] = temp + 1'b1;  
                            temp[8] = temp[7];  
                            case(IR[11:10])  
                                2'b00:begin  
                                    temp = {R0[7],R0}+temp;  
                                    R0 = temp[7:0];  
                                    end  
                                2'b01:begin  
                                    temp = {R1[7],R1}+temp;  
                                    R1 = temp[7:0];  
                                    end  
                                2'b10:begin  
                                    temp = {R2[7],R2}+temp;  
                                    R2 = temp[7:0];  
                                    end  
                                2'b11:begin  
                                    temp = {R3[7],R3}+temp;  
                                    R3 = temp[7:0];  
                                    end   
                            endcase  
                            end  
                        AND:begin  
                            case(IR[11:10])  
                                2'b00:R0 = R0 & Acc;  
                                2'b01:R1 = R1 & Acc;  
                                2'b10:R2 = R2 & Acc;  
                                2'b11:R3 = R3 & Acc;  
                            endcase  
                            end  
                        OR:begin  
                            case(IR[11:10])  
                                2'b00:R0 = R0 | Acc;  
                                2'b01:R1 = R1 | Acc;  
                                2'b10:R2 = R2 | Acc;  
                                2'b11:R3 = R3 | Acc;  
                            endcase  
                            end  
                        XOR:begin  
                            case(IR[11:10])  
                                2'b00:R0 = R0 ^ Acc;  
                                2'b01:R1 = R1 ^ Acc;  
                                2'b10:R2 = R2 ^ Acc;  
                                2'b11:R3 = R3 ^ Acc;  
                            endcase  
                            end  
                        Shr:begin  
                            case(IR[11:10])  
                                2'b00:R0 = R0 >>1;  
                                2'b01:R1 = R1 >>1;  
                                2'b10:R2 = R2 >>1;  
                                2'b11:R3 = R3 >>1;  
                            endcase  
                            end  
                        Shl:begin  
                            case(IR[11:10])  
                                2'b00:R0 = R0 <<1;  
                                2'b01:R1 = R1 <<1;  
                                2'b10:R2 = R2 <<1;  
                                2'b11:R3 = R3 <<1;  
                            endcase  
                            end  
                        Swap:begin  
                            case(IR[9:8])  
                                2'b00:case(IR[11:10])  
                                            2'b00:R0 = R0;  
                                            2'b01:R0 = R1;  
                                            2'b10:R0 = R2;  
                                            2'b11:R0 = R3;  
                                        endcase  
                                2'b01:case(IR[11:10])  
                                            2'b00:R1 = R0;  
                                            2'b01:R1 = R1;  
                                            2'b10:R1 = R2;  
                                            2'b11:R1 = R3;  
                                        endcase  
                                2'b10:case(IR[11:10])  
                                            2'b00:R2 = R0;  
                                            2'b01:R2 = R1;  
                                            2'b10:R2 = R2;  
                                            2'b11:R2 = R3;  
                                        endcase  
                                2'b11:case(IR[11:10])  
                                            2'b00:R3 = R0;  
                                            2'b01:R3 = R1;  
                                            2'b10:R3 = R2;  
                                            2'b11:R3 = R3;  
                                        endcase  
                            endcase  
                            end  
                        Jmp:begin   end  
                        Jz:begin    end  
                        Read:begin  end  
                        Write:begin end  
                        Stop:begin  end  
                    endcase  
                end   
            st_2:  
                begin  
                    case(IR[15:12])  
                        Swap:  
                            case(IR[11:10])  
                                2'b00:R0 = Acc;  
                                2'b01:R1 = Acc;  
                                2'b10:R2 = Acc;  
                                2'b11:R3 = Acc;  
                            endcase  
                        Jmp:begin  
                            IR[7:0] = M_data_in;  
                            PC = PC +1'b1;  
                            end  
                        Jz:begin  
                            IR[7:0] = M_data_in;  
                            PC = PC +1'b1;  
                            end  
                        Read:begin  
                            IR[7:0] = M_data_in;  
                            PC = PC +1'b1;  
                            end  
                        Write:begin  
                            IR[7:0] = M_data_in;  
                            PC = PC +1'b1;  
                            MDR = R0;  
                            end  
                    endcase  
                end  
            st_3:  
                begin  
                    case(IR[15:12])  
                        Jmp:PC = IR[11:0];  
                        Jz:begin  
                            if(R0==4'b0000)  
                                PC = IR[11:0];  
                        end  
                        Read:begin  end  
                        Write:begin end  
                    endcase  
                end  
            st_4:  
                begin  
                    case(IR[15:12])  
                        Read:R0 = M_data_in;  
                        Write:begin end  
                    endcase  
                end  
        endcase  
end  
  
always @(negedge clk,negedge reset)  
begin  
    if(reset == 1'b0)  
        begin  
            status = st_0;  
            Acc = 8'b0000_0000;  
            MAR = 8'b0000_0000;  
        end  
    else  
        case(status)  
            st_0:  
                begin  
                MAR = PC;  
                case(IR[9:8])  
                    2'b00:Acc = R0;  
                    2'b01:Acc = R1;  
                    2'b10:Acc = R2;  
                    2'b11:Acc = R3;  
                endcase  
                    status = st_1;  
                end  
            st_1:  
                begin  
                    case(IR[15:12])  
                        Swap:status = st_2;  
                        Jmp:status = st_2;  
                        Jz:status = st_2;  
                        Read:status = st_2;  
                        Write:status = st_2;  
                        default:status = st_0;  
                    endcase  
                end  
            st_2:  
                begin  
                    case(IR[15:12])  
                        Jmp:begin  
                            MAR = IR[11:0];  
                            status = st_3;  
                            end  
                        Jz:begin  
                            if(R0 == 4'b0000)  
                                MAR = IR[11:0];  
                            else  
                                MAR = PC;  
                            status = st_3;  
                            end  
                        Read:begin  
                            MAR = IR[11:0];  
                            status = st_3;  
                            end  
                        Write:begin  
                            MAR = IR[11:0];  
                            status = st_3;  
                            end  
                        default:status = st_0;  
                    endcase  
                end  
            st_3:  
                begin  
                    case(IR[15:12])  
                        Read:begin    
                            MAR = PC;  
                            status = st_4;  
                        end  
                        Write:begin   
                            MAR = PC;  
                            status = st_4;  
                        end  
                        default:status = st_0;  
                    endcase  
                end  
            st_4:status = st_0;  
        endcase  
end  
endmodule  

波形图部分:

(上图Load为2节拍,我之前写错了。。。这里忘了改了)

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值