'实验一
`timescale 1ns / 1ps
/* ALU模块实现两个32bit数的add、sub、and、or、not、slt功能,
但由于Nexy7输入口限制,将num1简化为8位,在过程中再extend成32位,num2作为内部wire自行赋值,此处赋为5
由于最后的结果在top.v中以七段数码管显示,32位结果不用以led在nexy4显示,因此输出32位结果没有问题*/
module alu(
input wire [2:0] op,
input wire [7:0] num1,
output reg [31:0] result
);
wire [31:0] num2;
wire [31:0] sign_extend_num1;
assign num2=32'h0000_0001;
assign sign_extend_num1={24'h0,num1};
always@(*)begin
case(op)
3'b000:result=sign_extend_num1+num2;
3'b001:result=sign_extend_num1-num2;
3'b010:result=sign_extend_num1&num2;
3'b011:result=sign_extend_num1|num2;
3'b100:result=~sign_extend_num1;
3'b101:begin
if(sign_extend_num1<num2) result=32'h0000_0001;
else result=32'h0000_0000;
end
default:result=32'hxxxx_xxxx;
endcase
end
endmodule
module display(
input wire clk,reset,
input wire [31:0]s,
output wire [6:0]seg,
output reg [7:0]ans
);
reg [20:0]count;
reg [3:0]digit;
always@(posedge clk,posedge reset)
if(reset)
count = 0;
else
count = count + 1;
always @(posedge clk)
case(count[20:18])
0:begin
ans = 8'b11111110;
digit = s[3:0];
end
1:begin
ans = 8'b11111101;
digit = s[7:4];
end
2:begin
ans = 8'b11111011;
digit =s[11:8];
end
3:begin
ans = 8'b11110111;
digit = s[15:12];
end
4:begin
ans = 8'b11101111;
digit = s[19:16];
end
5:begin
ans = 8'b11011111;
digit = s[23:20];
end
6:begin
ans = 8'b10111111;
digit =s[27:24];
end
7:begin
ans = 8'b01111111;
digit = s[31:28];
end
endcase
seg7 U4(.din(digit),.dout(seg));
endmodule
module seg7(
input wire [3:0]din,
output reg [6:0]dout
);
always@(*)
case(din)
5'h0:dout = 7'b000_0001;
5'h1:dout = 7'b100_1111;
5'h2:dout = 7'b001_0010;
5'h3:dout = 7'b000_0110;
5'h4:dout = 7'b100_1100;
5'h5:dout = 7'b010_0100;
5'h6:dout = 7'b010_0000;
5'h7:dout = 7'b000_1111;
5'h8:dout = 7'b000_0000;
5'h9:dout = 7'b000_0100;
5'ha:dout = 7'b000_1000;
5'hb:dout = 7'b110_0000;
5'hc:dout = 7'b011_0001;
5'hd:dout = 7'b100_0010;
5'he:dout = 7'b011_0000;
5'hf:dout = 7'b011_1000;
default:dout = 7'b111_1111;
endcase
module top(
input wire [2:0] op, //手动输入alu
input wire [7:0] num1, //手动输入alu
input wire clk,reset, //板子上clk、手动rst输入display
output wire [6:0]seg, //display输出
output wire [7:0]ans //display输出
);
wire [31:0] result; //alu输出进入display
alu gate1(op,num1,result);
display gate2(clk,reset,result,seg,ans);
endmodule
流水线加法器
二级流水线就是说把八位的加法分为两半去进行,即前一半和后一半,在前一半里有输入信号cin,后一半里接收前一半的进位信号count_temp
这个逗号就是说把两部分并在了一起,前一部分是4位的,后一部分也是4位的,所以连起来就是一个8位的,即最终的结果
至于4级流水其,就是将其分为4段,每段管两位的加法,然后一级一级的并起来,最后合起来就是8位的结果
如果被暂停的话,就向下一级传Z;刷新的话就是全部置0
这个是说一共32位,然后每算一级,就从最低位截取8位,表示这8位已经被计算,然后去记录哪些还没被计算的结果
sum2[7:0]<=sum1就是说直接继承上一级流水线的前8位结果
然后再计算的时候,是记录缓存里的tmpa1的前8位,然后是让未计算的再更新
先判断是否暂停,如果暂停的话就进位和结果都为z,然后当前级下的temp也都为z
接下来判断是否刷新,如果刷新就进位,结果都刷新,temp也刷新
接下来就是正常运行,如果可以的话,判断上一级进位是否传来一个z,如果传来一个z就说明上一级暂停了,那么这一位也要跟着暂停,进位之类的全都设置为z
不然就把已计算出的位数累加到寄存器上,然后记录本流水线上的结果
仿真
这个就是说每25ns翻转一次,那么就是500ns为10个周期,50ns为一个周期