时间:2024.12.24
Count15
代码
module top_module (input clk,input reset, // Synchronous active-high resetoutput [3:0] q);always@(posedge clk)beginif(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 resetoutput [3:0] q);always@(posedge clk)beginq <= reset==1?4'd0:q+1'b1;end
endmodule
运行结果
Shift4
代码
module top_module(input clk,input areset, // async active-high reset to zeroinput load,input ena,input [3:0] data,output reg [3:0] q); always@(posedge clk or posedge areset)beginif(areset)beginq<=4'd0;end else if(load)beginq<=data;end else if(ena)beginq<=q>>1;end else beginq<=q;endend
endmodule
module top_module(input clk,input areset, // async active-high reset to zeroinput load,input ena,input [3:0] data,output reg [3:0] q); always@(posedge clk or posedge areset)beginif(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 circuitcase(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;endcaseendendmodule
运行结果
Always case2(优先级编码器)
代码
// synthesis verilog_input_version verilog_2001
module top_module (input [3:0] in,output reg [1:0] pos );always@(*)beginif(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;elsepos = 2'd0;end
endmodule
运行结果
Count10
代码
module top_module (input clk,input reset, // Synchronous active-high resetoutput [3:0] q);always@(posedge clk)beginif(reset) q<=4'd0;else beginif(q==4'd9) q<=4'd0;else q<=q+4'd1;endend
endmodule
module top_module (input clk,input reset, // Synchronous active-high resetoutput [3:0] q);/*//方法一:三目运算符always@(posedge clk)beginq <= reset==1||q==4'd9 ? 4'd0 : q+1'b1;end*///方法二:if-else结构always@(posedge clk)beginif(reset)beginq <= 4'd0;end else beginif(q==4'd9)beginq <= 4'd0;end else beginq <= q + 1'b1;endendend
endmodule
运行结果
Count1to10
代码
module top_module (input clk,input reset,output [3:0] q);always@(posedge clk)beginif(reset) q<=4'd1;else beginif(q==4'd10) q<=4'd1;else q<=q+4'd1;endend
endmodule
module top_module (input clk,input reset,output [3:0] q);always@(posedge clk)beginq<=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)beginif(reset)beginq<=4'd0;end else beginif(slowena && q==9)beginq<=4'd0;end else if(slowena) beginq<=q+1'b1;end else beginq<=q;endendend
endmodule
module top_module (input clk,input slowena,input reset,output [3:0] q);always@(posedge clk)beginif(reset)q<=4'd0;else beginif(slowena )beginif(q==4'd9)beginq<=4'd0;end else q<=q+1'b1;end else q<=q;endend
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@(*)beginif(reset)beginc_d<=4'd1;c_load<=1'b1;end else beginif(enable && Q==4'd12)beginc_d<=4'd1;c_load<=1'b1;end else beginc_d<=c_d; //此种写法有latch警告//c_d<=1'b0; //也可赋0c_load<=1'b0;endendendassign 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 resetoutput [3:1] ena,output [15:0] q);always@(posedge clk)beginena[1]<=1'b0;if(reset)beginq<=16'h0;endelse if(q[3:0]==4'd9) beginq[3:0]<=4'd0;ena[1]<=1'b1;endelse beginq[3:0]<=q[3:0]+4'd1;endif(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) beginif (reset)bcd0 <= 4'b0000;else if (bcd0 == 4'b1001)bcd0 <= 4'b0000;elsebcd0 <= bcd0 + 1;end// 十位计数器,当个位从9变为0时,十位加1always @(posedge clk) beginif (reset)bcd1 <= 4'b0000;else if (bcd0 == 4'b1001) beginif (bcd1 == 4'b1001)bcd1 <= 4'b0000;elsebcd1 <= bcd1 + 1;endend// 百位计数器,当十位从9变为0时,百位加1always @(posedge clk) beginif (reset)bcd2 <= 4'b0000;else if (bcd1 == 4'b1001 && bcd0 == 4'b1001) beginif (bcd2 == 4'b1001)bcd2 <= 4'b0000;elsebcd2 <= bcd2 + 1;endend// 千位计数器,当百位从9变为0时,千位加1always @(posedge clk) beginif (reset)bcd3 <= 4'b0000;else if (bcd2 == 4'b1001 && bcd1 == 4'b1001 && bcd0 == 4'b1001) beginif (bcd3 == 4'b1001)bcd3 <= 4'b0000;elsebcd3 <= bcd3 + 1;endend// 连接输出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 时为高电平。
运行结果