时间:2024.12.24
Count15

代码
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always@(posedge clk)
begin
if(reset) q<=4'b0;
else if(q==4'b1111)
q<=4'b0000;
else q<=q+4'b0001;
end
endmodule
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always@(posedge clk)begin
q <= reset==1?4'd0:q+1'b1;
end
endmodule
运行结果

Shift4

代码
module top_module(
input clk,
input areset, // async active-high reset to zero
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
always@(posedge clk or posedge areset)begin
if(areset)begin
q<=4'd0;
end else if(load)begin
q<=data;
end else if(ena)begin
q<=q>>1;
end else begin
q<=q;
end
end
endmodule
module top_module(
input clk,
input areset, // async active-high reset to zero
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
always@(posedge clk or posedge areset)begin
if(areset)
q<=4'd0;
else if(load)
q<=data;
else if(ena)
q<=q>>1;
//else
// q<=q;
end
endmodule
运行结果

Always if

代码
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
assign out_assign=(sel_b1&sel_b2)?b:a;
always@(*)
out_always=(sel_b1&sel_b2)?b:a;
endmodule

运行结果

Always case(多路转换器)

代码
// synthesis verilog_input_version verilog_2001
module top_module (
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5,
output reg [3:0] out );//
always@(*) begin // This is a combinational circuit
case(sel)
3'd0:out=data0;
3'd1:out=data1;
3'd2:out=data2;
3'd3:out=data3;
3'd4:out=data4;
3'd5:out=data5;
default:out=4'b0000;
endcase
end
endmodule

运行结果


Always case2(优先级编码器)

代码
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)begin
if(in[0]==1)
pos = 2'd0;
else if(in[1]==1)
pos = 2'd1;
else if(in[2]==1)
pos = 2'd2;
else if(in[3]==1)
pos = 2'd3;
else
pos = 2'd0;
end
endmodule


运行结果

Count10

代码
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always@(posedge clk)
begin
if(reset) q<=4'd0;
else begin
if(q==4'd9) q<=4'd0;
else q<=q+4'd1;
end
end
endmodule
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
/*//方法一:三目运算符
always@(posedge clk)begin
q <= reset==1||q==4'd9 ? 4'd0 : q+1'b1;
end*/
//方法二:if-else结构
always@(posedge clk)begin
if(reset)begin
q <= 4'd0;
end else begin
if(q==4'd9)begin
q <= 4'd0;
end else begin
q <= q + 1'b1;
end
end
end
endmodule
运行结果

Count1to10

代码
module top_module (
input clk,
input reset,
output [3:0] q);
always@(posedge clk)
begin
if(reset) q<=4'd1;
else begin
if(q==4'd10) q<=4'd1;
else q<=q+4'd1;
end
end
endmodule
module top_module (
input clk,
input reset,
output [3:0] q);
always@(posedge clk)begin
q<=reset==1||q==10?4'd1:q+1'b1;
end
endmodule
运行结果

Countslow

代码(可以用条件语句的嵌套)
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always@(posedge clk)begin
if(reset)begin
q<=4'd0;
end else begin
if(slowena && q==9)begin
q<=4'd0;
end else if(slowena) begin
q<=q+1'b1;
end else begin
q<=q;
end
end
end
endmodule
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always@(posedge clk)begin
if(reset)
q<=4'd0;
else begin
if(slowena )begin
if(q==4'd9)
begin
q<=4'd0;
end
else q<=q+1'b1;
end else q<=q;
end
end
endmodule
运行结果


Exams/ece241 2014 q7a


代码
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d
);
always@(*)begin
if(reset)begin
c_d<=4'd1;
c_load<=1'b1;
end else begin
if(enable && Q==4'd12)begin
c_d<=4'd1;
c_load<=1'b1;
end else begin
c_d<=c_d; //此种写法有latch警告
//c_d<=1'b0; //也可赋0
c_load<=1'b0;
end
end
end
assign c_enable=enable;
count4 count4_inst (
.clk(clk),
.enable(c_enable),
.load(c_load),
.d(c_d),
.Q(Q));
endmodule
运行结果



Countbcd

错误代码
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
always@(posedge clk)
begin
ena[1]<=1'b0;
if(reset)
begin
q<=16'h0;
end
else if(q[3:0]==4'd9) begin
q[3:0]<=4'd0;
ena[1]<=1'b1;
end
else begin
q[3:0]<=q[3:0]+4'd1;
end
if(ena[1]==1) q[7:4]<=q[7:4]+4'd1;
else q[7:4]<=q[7:4];
end
endmodule
错误分析
- 计数逻辑不完整 :
- 原代码只处理了个位(
q[3:0]
)和十位(q[7:4]
)部分的计数逻辑,没有对百位(q[11:8]
)以及千位(q[15:12]
)进行相应的处理,无法实现完整的 4 位 BCD 计数器功能,不符合题目要求的能从 0 计数到 9999 的需求。 - 对于十位的计数逻辑虽然在
ena[1]
为 1 时进行了加 1 操作,但没有考虑十位计数满 9 后要清零以及向更高位进位等情况,同样百位和千位的相关逻辑缺失。
- 原代码只处理了个位(
- 复位逻辑局限性 :
- 原代码中
reset
信号只对整个计数器的初始值进行了简单的清零操作(将q
赋值为16'h0
),但在后续的计数过程中,没有针对复位情况对各个数位的计数状态进行完整的重置,例如当在计数过程中出现复位信号,所有数位都应该立即清零,而不仅仅是初始化那一次起作用。
- 原代码中
- 组合逻辑使用不当(可能产生锁存器) :
- 在代码中对于
ena[1]
以及q[7:4]
等的赋值逻辑存在一些问题,像else q[7:4]<=q[7:4];
这样的语句其实是不必要的,并且在always
块内这种不完全赋值的情况(不是在所有分支都对q[7:4]
等信号进行明确赋值),可能会导致综合出锁存器,而不是期望的纯组合逻辑或者时序逻辑行为,这不符合良好的代码规范和设计意图。
- 在代码中对于
运行结果



正确代码
module top_module (
input clk,
input reset,
output [3:1] ena,
output [15:0] q
);
// 定义4个一位的BCD计数器
reg [3:0] bcd0;
reg [3:0] bcd1;
reg [3:0] bcd2;
reg [3:0] bcd3;
// 个位计数器
always @(posedge clk) begin
if (reset)
bcd0 <= 4'b0000;
else if (bcd0 == 4'b1001)
bcd0 <= 4'b0000;
else
bcd0 <= bcd0 + 1;
end
// 十位计数器,当个位从9变为0时,十位加1
always @(posedge clk) begin
if (reset)
bcd1 <= 4'b0000;
else if (bcd0 == 4'b1001) begin
if (bcd1 == 4'b1001)
bcd1 <= 4'b0000;
else
bcd1 <= bcd1 + 1;
end
end
// 百位计数器,当十位从9变为0时,百位加1
always @(posedge clk) begin
if (reset)
bcd2 <= 4'b0000;
else if (bcd1 == 4'b1001 && bcd0 == 4'b1001) begin
if (bcd2 == 4'b1001)
bcd2 <= 4'b0000;
else
bcd2 <= bcd2 + 1;
end
end
// 千位计数器,当百位从9变为0时,千位加1
always @(posedge clk) begin
if (reset)
bcd3 <= 4'b0000;
else if (bcd2 == 4'b1001 && bcd1 == 4'b1001 && bcd0 == 4'b1001) begin
if (bcd3 == 4'b1001)
bcd3 <= 4'b0000;
else
bcd3 <= bcd3 + 1;
end
end
// 连接输出
assign q[3:0] = bcd0;
assign q[7:4] = bcd1;
assign q[11:8] = bcd2;
assign q[15:12] = bcd3;
// 产生ena信号
assign ena[1] = (bcd0 == 4'b1001);
assign ena[2] = (bcd1 == 4'b1001) && (bcd0 == 4'b1001);
assign ena[3] = (bcd2 == 4'b1001) && (bcd1 == 4'b1001) && (bcd0 == 4'b1001);
endmodule
这段代码实现了一个 4 - 位 BCD 计数器。每个十进制数位由 4 位二进制数表示。代码中定义了 4 个一位的 BCD 计数器(bcd0
、bcd1
、bcd2
和bcd3
)分别代表个位、十位、百位和千位。
-
个位计数器(
bcd0
) :在每个时钟上升沿,如果reset
信号为高电平,计数器清零;如果计数器达到 9(4'b1001
),则在下一个时钟上升沿清零,否则计数器加 1。 -
十位计数器(
bcd1
) :在每个时钟上升沿,如果reset
信号为高电平,计数器清零;当个位计数器从 9 变为 0 时,十位计数器加 1;如果十位计数器达到 9,则在下一个时钟上升沿清零,否则计数器加 1。 -
百位计数器(
bcd2
) :在每个时钟上升沿,如果reset
信号为高电平,计数器清零;当十位和个位计数器都从 9 变为 0 时,百位计数器加 1;如果百位计数器达到 9,则在下一个时钟上升沿清零,否则计数器加 1。 -
千位计数器(
bcd3
) :在每个时钟上升沿,如果reset
信号为高电平,计数器清零;当百位、十位和个位计数器都从 9 变为 0 时,千位计数器加 1;如果千位计数器达到 9,则在下一个时钟上升沿清零,否则计数器加 1。 -
输出连接(
assign
) :将各个 BCD 计数器的值连接到 16 位输出q
上。 -
ena
信号产生 :ena
信号用于指示何时高位计数器应该加 1。ena[1]
在个位计数器达到 9 时为高电平,ena[2]
在十位和个位计数器都达到 9 时为高电平,ena[3]
在百位、十位和个位计数器都达到 9 时为高电平。
运行结果
