实验要求
使用Verilog语言,设计2个计数器
计数器1字长3比特,无符号数制,从0计数到7。
计数器2字长4比特,二补码数制,从-7 计数到7。(注意危险的1000,这是-8)
自行设计符号扩展规则,把两个计数器的输出信号进行字长匹配,然后相加
自行设定相加之后的字长。
验证两个计数值相加之后的正确性。
可以使用modelsim或是quartus的波形仿真或是signalTAP
- 计数器1字长3比特,无符号数制,从0计数到7。
module cnt_0to7(clk, rst_n, cnt_1);
input clk;
input rst_n;
output reg [2:0] cnt_1;
parameter T= 7;
always @ (posedge clk)
begin
if(!rst_n)
cnt_1 <= 0;
else if(cnt_1 == T)
cnt_1 <= 0;
else
cnt_1 <= cnt_1 + 1'b1; end endmodule
2.计数器2字长4比特,二补码数制,从-7 计数到7。
module cnt__7to7(clk, rst_n, cnt_2);
input clk, rst_n;
output [3:0] cnt_2;
reg signed [3:0] cnt_2;
always @ (posedge clk)
begin
if(!rst_n)
cnt_2 <= 4'sb1001;
else if(cnt_2==4'b0111)
cnt_2 <= 4'b1001;
else
cnt_2 <= cnt_2 + 4'sb0001;
end
endmodule
3.符号扩展为4位,把两个计数器的输出信号进行字长匹配,然后相加
module and_cnt(clk, rst_n, sum);
input clk, rst_n;
output sum;
reg signed [4-1:0] sum;
reg signed [4-1:0] cnt_1_3to4;
wire signed [3-1:0] cnt_1;
wire signed [4-1:0] cnt_2;
cnt_0to7 a(.clk(clk), .rst_n(rst_n), .cnt_1(cnt_1));
always @ (cnt_1)
begin
cnt_1_3to4 = {1'sb0,cnt_1};
end
cnt__7to7 b(.clk(clk), .rst_n(rst_n), .cnt_2(cnt_2));
always @ (cnt_1_3to4 or cnt_2)
begin
sum = cnt_1_3to4 + cnt_2;
end
endmodule
从modelsim截图中可以看到有溢出产生
4.符号扩展为5位,把两个计数器的输出信号进行字长匹配,然后相加
module and_cnt_2(clk, rst_n, sum);
input clk, rst_n;
output reg signed [5-1:0] sum;
reg signed [4:0] cnt_1_3to5;
reg signed [4:0] cnt_2_4to5;
wire signed [2:0] cnt_1;
wire signed [3:0] cnt_2;
cnt_0to7 a(.clk(clk), .rst_n(rst_n), .cnt_1(cnt_1));
always @ (cnt_1)
begin
cnt_1_3to5 = {2'b00,cnt_1};
end
cnt__7to7 b(.clk(clk), .rst_n(rst_n), .cnt_2(cnt_2));
always @ (cnt_2)
begin
if(cnt_2[3] == 0)
cnt_2_4to5 = {1'b0,cnt_2};
else
cnt_2_4to5 = {1'b1,cnt_2};
end
always @ (cnt_1_3to5 or cnt_2_4to5)
begin
sum = cnt_1_3to5 + cnt_2_4to5;
end
endmodule
截图中可以看到该段及未显示段均正确
总结(定点数相加字长问题)
1.首先将两个定点数扩展为相同bit数,建议与和的bit数相同
2.简单计算相加和的最大值,从而确定和的bit数。&注意此时要考虑到符号位是否存在,若符号位存在,应预留出符号位,即扩展为实际长度+1