计算机组成原理实验 - 实验六:运算器设计
实验内容
将算术逻辑单元与寄存器组集成,设计简单的运算器。
Sin,Sout:
Sin | Sout | 寄存器输入信号 | 寄存器输出信号 |
---|---|---|---|
0 | 0 | 键盘输入 | PC |
0 | 1 | 键盘输入 | res,即R[RA] |
1 | 0 | ALU计算结果输入 | PC |
1 | 1 | ALU计算结果输入 | res,即R[RA] |
R0-R3:
寄存器 | 控制信号 RA1 RA0 Wr Rd | 操作 |
---|---|---|
R0 | 0 0 0 1 | 写入 |
R0 | 0 0 1 0 | 读出 |
R1 | 0 1 0 1 | 写入 |
R1 | 0 1 1 0 | 读出 |
R2 | 1 0 0 1 | 写入 |
R2 | 1 0 1 0 | 读出 |
R3 | 1 1 0 1 | 写入 |
R3 | 11 1 0 | 读出 |
RA控制R0~R3的选择,Wr和Rd控制输入和输出。
PC:
寄存器 | 控制信号 M1 M0 | 操作 |
---|---|---|
PC | 0 0 | 置数 |
PC | 0 1 | 加一计数 |
PC | 1 0 | 减一计数 |
PC | 1 1 | 保持 |
reset为低电平有效的PC清零信号。
ALU:
控制信号 s2 s1 s0 | 实现功能 |
---|---|
000 | F清零 |
001 | A与B逻辑乘(&) |
010 | A与B逻辑加(|) |
011 | A与B逻辑异或(^) |
100 | A与B算数加 |
101 | A逻辑左移一位 |
110 | A逻辑右移一位 |
111 | A算数右移一位 |
实验代码
顶层设计
注:实验和仿真时要对应的修改bdf中的Parameter的值!
CPU寄存器 CPU_register_group
注:l用于分频,clk_alt是分频时钟信号。
module CPU_register_group(
input [1:0] M,RA,
input [7:0] D,
input wr,rd,reset,
input clk,
output reg [7:0] PC,res,
output reg[7:0] R0,R1,R2,R3
);
reg clk_alt;
reg [9:0] l;
parameter wei = 9;
always@(negedge clk) //分频
begin
l<=l+1;
clk_alt<=l[wei];
end
always @(negedge clk_alt or negedge reset) //处理PC的值
begin
if(!reset)
PC = 0;
else
begin
case(M)
0:PC = D;
1:PC = PC+1;
2:PC = PC-1;
default:PC = PC;
endcase
end
end
always @(negedge clk) //处理寄存器的值
begin
case(RA)
0:begin
if(wr==0&&rd==1)
R0=D;
else if(wr==1&&rd==0)
res=R0;
end
1:begin
if(wr==0&&rd==1)
R1=D;
else if(wr==1&&rd==0)
res=R1;
end
2:begin
if(wr==0&&rd==1)
R2=D;
else if(wr==1&&rd==0)
res=R2;
end
3:begin
if(wr==0&&rd==1)
R3=D;
else if(wr==1&&rd==0)
res=R3;
end
endcase
end
endmodule
矩阵键盘 keymodule
注:COUNT_MAX用于防抖,当其小于10左右会出现抬起抖动读取,建议在实验时设置为100或1000;在仿真时设置为1。
注:因为clr绑定在按钮上,而按键按下为低电平,所以清理信号低电平有效,改为!clr。
module keymodule(
input clk,
input [3:0] KEY_C,
input clr,
output reg[3:0] KEY_R,
output reg[15:0] out
);
parameter COUNT_MAX = 32'd1000; //没有按键按下的延迟时间
reg [1:0] cnt = 2'd0;
reg [4:0] num =5'd16;
reg [31:0] count_num=COUNT_MAX;
initial
KEY_R = 4'b1110;
//根据按钮的列扫描信号和行输入信号判断按钮是否被按下
always @(posedge clk,negedge clr)
begin
if(!clr)
begin
cnt<=2'b0;
out<=16'h0000;
count_num<=COUNT_MAX; //让下一次就能读取
end
else
begin
if(KEY_C==4'b1111)
begin
//num = 5'd16;
cnt = cnt + 1'b1;
case (cnt)
2'b00: KEY_R <= 4'b1110;
2'b01: KEY_R <= 4'b1101;
2'b10: KEY_R <= 4'b1011;
2'b11: KEY_R <= 4'b0111;
endcase
//计数分频防止位移过快
if(count_num < COUNT_MAX)
count_num = count_num + 1'b1;
end
else
begin
case ({KEY_C, KEY_R})
8'b_1110_1011: num = 5'd0;
8'b_0111_0111: num = 5'd1;
8'b_0111_1011: num = 5'd2;
8'b_0111_1101: num = 5'd3;
8'b_1011_0111: num = 5'd4;
8'b_1011_1011: num = 5'd5;
8'b_1011_1101: num = 5'd6;
8'b_1101_0111: num = 5'd7;
8'b_1101_1011: num = 5'd8;
8'b_1101_1101: num = 5'd9;
8'b_0111_1110: num = 5'd10;
8'b_1011_1110: num = 5'd11;
8'b_1101_1110: num = 5'd12;
8'b_1110_1110: num = 5'd13;
8'b_1110_0111: num = 5'd14;
8'b_1110_1101: num = 5'd15;
endcase
if(count_num >= COUNT_MAX) //没有按键按下的空闲时间够长(防抖)
begin
count_num = 32'b0;
//移位
out=out<<4;
out[3:0] = num[3:0];
end
end //end KER_R!=4'b1111
end //end if(clr) else
end //end always
endmodule
数码管输出 segment_displays
module segment_displays(
input clk,
input [31:0] N,
output reg [7:0] seg,
output reg [2:0] sel
);
reg [3:0] num;
always@(posedge clk)
begin
sel=sel+1;
case(sel)
3'b000:num=N[31:28];
3'b001:num=N[27:24];
3'b010:num=N[23:20];
3'b011:num=N[19:16];
3'b100:num=N[15:12];
3'b101:num=N[11:8];
3'b110:num=N[7:4];
3'b111:num=N[3:0];
endcase
end
always@(num)
begin
case(num)
4'h0:seg=8'b00111111; //"0"
4'h1:seg=8'b00000110; //"1"
4'h2:seg=8'b01011011; //"2"
4'h3:seg=8'b01001111; //"3”
4'h4:seg=8'b01100110; //"4"
4'h5:seg=8'b01101101; //"5"
4'h6:seg=8'b01111101; //"6"
4'h7:seg=8'b00000111; //"8"
4'h8:seg=8'b01111111; //"8"
4'h9:seg=8'b01101111; //"9"
4'hA:seg=8'b01110111; //"A"
4'hB:seg=8'b01111100; //"b"
4'hC:seg=8'b00111001; //"c"
4'hD:seg=8'b01011110; //"d"
4'hE:seg=8'b01111001; //"E"
4'hF:seg=8'b01110001; //"F"
default:seg=8'b00000000; //"dark"
endcase
end
endmodule
ALU的暂存器组 midware
module midware(
input clk,
input [7:0]in,
input sel,
input wt,
output reg [7:0] X,
output reg [7:0] Y
);
always @(posedge clk)
begin
if(wt)
if(!sel)
X = in[7:0];
else
Y = in[7:0];
end
endmodule
ALU运算器
注:cin绑定在按键上,所以改为!cin。
module ALU(
input clk,
input [2:0] s,
input cin,
input [7:0] A,
input [7:0] B,
output reg overflow,
output reg [7:0] F
);
reg [8:0] C;
always@(posedge clk)
begin
case(s)
3'b000: //F清零
begin
overflow=0;
F=0;
end
3'b001: //逻辑乘
begin
overflow=0;
F=A&B;
end
3'b010: //逻辑加
begin
overflow=0;
F=A|B;
end
3'b011: //逻辑异或
begin
overflow=0;
F=A^B;
end
3'b100: //算术加
begin
C = {A[7],A[7:0]}+{B[7],B[7:0]} + !cin;
F = C[7:0];
overflow = C[8]^C[7];
end
3'b101: //逻辑左移
begin
overflow=0;
F = {A[6:0],1'b0};
end
3'b110: //逻辑右移
begin
overflow=0;
F = {1'b0,A[7:1]};
end
3'b111: //算数右移
begin
overflow=0;
F = {A[7],A[7:1]};
end
endcase
end
endmodule
仿真波形
引脚配置
Node Name | Direction | Location | I/O Bark | - | - | - | - |
---|---|---|---|---|---|---|---|
cin | Input | PIN_AH8 | 3 | B3_N1 | PIN_AH8 | 2.5 V (default) | 8mA (default) |
clk | Input | PIN_A14 | 8 | B8_N0 | PIN_A14 | 2.5 V (default) | 8mA (default) |
clr | Input | PIN_AH7 | 3 | B3_N2 | PIN_AH7 | 2.5 V (default) | 8mA (default) |
key_c[3] | PIN_AE14 | 3 | B3_N0 | PIN_AE14 | 2.5 V (default) | 8mA (default) | |
key_c[2] | PIN_AF13 | 3 | B3_N1 | PIN_AF13 | 2.5 V (default) | 8mA (default) | |
key_c[1] | PIN_AD12 | 3 | B3_N3 | PIN_AD12 | 2.5 V (default) | 8mA (default) | |
key_c[0] | PIN_AD11 | 3 | B3_N3 | PIN_AD11 | 2.5 V (default) | 8mA (default) | |
key_out[3] | PIN_E24 | 6 | B6_N0 | PIN_E24 | 2.5 V (default) | 8mA (default) | 2 (default) |
key_out[2] | PIN_F22 | 7 | B7_N0 | PIN_F22 | 2.5 V (default) | 8mA (default) | 2 (default) |
key_out[1] | PIN_E22 | 7 | B7_N0 | PIN_E22 | 2.5 V (default) | 8mA (default) | 2 (default) |
key_out[0] | PIN_F21 | 7 | B7_N0 | PIN_F21 | 2.5 V (default) | 8mA (default) | 2 (default) |
key_r[3] | PIN_AE11 | 3 | B3_N0 | PIN_AE11 | 2.5 V (default) | 8mA (default) | 2 (default) |
key_r[2] | PIN_AF11 | 3 | B3_N1 | PIN_AF11 | 2.5 V (default) | 8mA (default) | 2 (default) |
key_r[1] | PIN_AE12 | 3 | B3_N0 | PIN_AE12 | 2.5 V (default) | 8mA (default) | 2 (default) |
key_r[0] | PIN_AE13 | 3 | B3_N0 | PIN_AE13 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[7] | PIN_M21 | 6 | B6_N1 | PIN_M21 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[6] | PIN_G12 | 8 | B8_N2 | PIN_G12 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[5] | PIN_G14 | 8 | B8_N0 | PIN_G14 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[4] | PIN_G15 | 7 | B7_N3 | PIN_G15 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[3] | PIN_G18 | 7 | B7_N2 | PIN_G18 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[2] | PIN_F18 | 7 | B7_N1 | PIN_F18 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[1] | PIN_G17 | 7 | B7_N2 | PIN_G17 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_seg[0] | PIN_G16 | 7 | B7_N3 | PIN_G16 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_sel[2] | PIN_G9 | 8 | B8_N3 | PIN_G9 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_sel[1] | PIN_D22 | 7 | B7_N0 | PIN_D22 | 2.5 V (default) | 8mA (default) | 2 (default) |
LED_sel[0] | PIN_C22 | 7 | B7_N1 | PIN_C22 | 2.5 V (default) | 8mA (default) | 2 (default) |
M[1] | Input | PIN_AA10 | 3 | B3_N1 | PIN_AA10 | 2.5 V (default) | 8mA (default) |
M[0] | Input | PIN_U8 | 2 | B2_N3 | PIN_U8 | 2.5 V (default) | 8mA (default) |
overflow | PIN_AE8 | 3 | B3_N3 | PIN_AE8 | 2.5 V (default) | 8mA (default) | 2 (default) |
RA[1] | PIN_AF12 | 3 | B3_N1 | PIN_AF12 | 2.5 V (default) | 8mA (default) | |
RA[0] | PIN_AG12 | 3 | B3_N0 | PIN_AG12 | 2.5 V (default) | 8mA (default) | |
rd | Input | PIN_AH6 | 3 | B3_N2 | PIN_AH6 | 2.5 V (default) | 8mA (default) |
reset | Input | PIN_AE3 | 2 | B2_N3 | PIN_AE3 | 2.5 V (default) | 8mA (default) |
s[2] | Input | PIN_AA8 | 2 | B2_N1 | PIN_AA8 | 2.5 V (default) | 8mA (default) |
s[1] | Input | PIN_AB8 | 2 | B2_N3 | PIN_AB8 | 2.5 V (default) | 8mA (default) |
s[0] | Input | PIN_AE4 | 2 | B2_N3 | PIN_AE4 | 2.5 V (default) | 8mA (default) |
sel | Input | PIN_AD4 | 2 | B2_N3 | PIN_AD4 | 2.5 V (default) | 8mA (default) |
sin | Input | PIN_AH12 | 3 | B3_N1 | PIN_AH12 | 2.5 V (default) | 8mA (default) |
sout | Input | PIN_AF14 | 3 | B3_N0 | PIN_AF14 | 2.5 V (default) | 8mA (default) |
wr | Input | PIN_AF5 | 3 | B3_N2 | PIN_AF5 | 2.5 V (default) | 8mA (default) |
wt | Input | PIN_AC5 | 2 | B2_N3 | PIN_AC5 | 2.5 V (default) | 8mA (default) |