?代碼部分:
module CPU(
input clk, //時鐘
input reset, //復(fù)位
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; //程序計數(shù)器
reg[15:0]IR; //指令寄存器
reg [7:0]Acc; //累加寄存器/臨時寄存器
reg [8:0]temp; //加減運(yùn)算擴(kuò)充符號位后的臨時寄存器
reg [11:0]MAR; //內(nèi)存地址寄存器
reg [7:0]MDR; //內(nèi)存數(shù)據(jù)寄存器
assign M_address = MAR;
assign M_data_out = MDR;
//狀態(tài)
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的補(bǔ)碼,將補(bǔ)碼減法變?yōu)檠a(bǔ)碼加法 (x-y)補(bǔ)=x補(bǔ)+(-y)
//對于這里沒有直接將-Acc的補(bǔ)碼存在Acc寄存器里的解釋:
//因為在時鐘下降沿那個always塊里有Acc的賦值,同一個寄存器的賦值不能出現(xiàn)在多個always語句里,會產(chǎn)生沖突
//雖然一個時鐘上升沿一個時鐘下降沿不會產(chǎn)生沖突,但是編譯時仍會報錯
//這也是為什么寄存器的清零一部分放在時鐘上升沿時,一部分放在時鐘下降沿時
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節(jié)拍,我之前寫錯了。。。這里忘了改了)
文章來源:http://www.zghlxwxcb.cn/news/detail-536427.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-536427.html
到了這里,關(guān)于西南交通大學(xué) 計算機(jī)組成原理實驗課程設(shè)計的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!