'实验一
`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@(*)begincase(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:beginif(sign_extend_num1<num2) result=32'h0000_0001;else result=32'h0000_0000;enddefault:result=32'hxxxx_xxxx;endcaseendendmodule
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:beginans = 8'b11111110;digit = s[3:0];end1:beginans = 8'b11111101;digit = s[7:4];end2:beginans = 8'b11111011;digit =s[11:8];end3:beginans = 8'b11110111;digit = s[15:12];end4:beginans = 8'b11101111;digit = s[19:16];end5:beginans = 8'b11011111;digit = s[23:20];end6:beginans = 8'b10111111;digit =s[27:24];end7:beginans = 8'b01111111;digit = s[31:28];endendcaseseg7 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, //手动输入aluinput wire [7:0] num1, //手动输入aluinput wire clk,reset, //板子上clk、手动rst输入displayoutput wire [6:0]seg, //display输出output wire [7:0]ans //display输出);wire [31:0] result; //alu输出进入displayalu 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为一个周期