verilog - 如何在 Verilog 中编程延迟?
问题描述
我正在尝试使用 LED 显示莫尔斯电码。我需要一个半秒的光脉冲来代表一个点,一个 1.5 秒的脉冲来代表一个破折号。
我真的被困在这里了。我在我的 FPGA 上使用内部 50MHz 时钟制作了一个计数器。我必须制造的机器将输入一个 3 位数字并将其转换为莫尔斯字母,AH,A 为 000,B 为 001,依此类推。我只需要弄清楚如何告诉 FPGA 让 LED 在指定的时间内保持打开状态,然后关闭大约一秒钟(这将是点脉冲和短划线脉冲之间的延迟)。
任何提示将非常感谢。此外,它必须是可合成的。
这是我的代码。它还没有运行。它一直给我的错误信息是:
错误 (10028):无法在 part4.v(149) 解析网络“c3[0]”的多个常量驱动程序
module part4 (SELECT, CLK, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, CLK, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; //goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3; //keeps track of the index we are on in the code.
reg [3:0] STATE; //register to keep track of states in the state machine
reg done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1 to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
parameter START= 4'b000, DOT= 4'b001, DASH= 4'b010, DELAY= 4'b011, IDLE=
4'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always @(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==8'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always @(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
COUNT2 <= 0;
else if ((COUNT2==2)&&(halfsecflag==1))
begin
COUNT2 = 0;
dashflag=1;
end
else if (halfsecflag==1)
COUNT2= COUNT2+1;
end
always @(RESET) //asynchronous reset
begin
STATE=IDLE;
end
always@(STATE) //State machine
begin
done=0;
case(STATE)
START: begin
led = 1;
if (i) STATE = DOT;
else STATE = DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE = DELAY;
else if (ending) STATE= IDLE;
else STATE=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE = DELAY;
else if (ending)
STATE = IDLE;
else STATE = DASH;
end
DELAY: begin
led = 0;
if ((halfsecflag)&&(ending))
STATE=IDLE;
else if ((halfsecflag)&&(~ending))
begin
done=1;
STATE=START;
end
else STATE = DELAY;
end
IDLE: begin
c3=0;
if (CLK) STATE=START;
else STATE=IDLE;
end
default: STATE = IDLE;
endcase
end
always @(posedge CLK)
begin
case (SELECT)
A: length=2'b01;
B: length=2'b11;
C: length=2'b11;
D: length=2'b10;
E: length=2'b00;
F: length=2'b11;
G: length=2'b10;
H: length=2'b11;
default: length=2'bxx;
endcase
end
always @(posedge CLK)
begin
case (SELECT)
A: code= 4'b0001;
B: code= 4'b1110;
C: code= 4'b1010;
D: code= 4'b0110;
E: code= 4'b0001;
F: code= 4'b1011;
G: code= 4'b0100;
H: code= 4'b1111;
default: code=4'bxxxx;
endcase
end
always @(posedge CLK)
begin
if (c3==length)
begin
c3<=0; ending=1;
end
else if (done)
c3<= c3+1;
end
endmodule
解决方案
我一直在阅读您的代码,并且有很多问题:
代码未格式化。
您没有提供测试台。你写了一个吗?
“无法解析网络的多个常量驱动程序”在堆栈交换中搜索错误消息。已经被问过很多次了。
总是使用 @(*) 而不是总是使用 @(STATE) 你缺少像
i, halfsecflag, ending
. 但请参阅第 6 点:您希望状态位于时钟部分。在总是使用 @(posedge CLK) 的地方,您必须使用非阻塞分配:
<=
.有很多地方你使用
always @(posedge CLK)
你想使用的地方always @(*)
(例如你设置的地方length
和code
) 对面你想使用posedge CLK
你使用你的状态的地方。只使用一个时钟和一个时钟。不要使用 CLK和CLOCK_50。使用其中之一。
注意你的矢量大小。这
8'd25000000
是错误的,因为您无法将 25000000 放入 8 位中。
你的使用halfsecflag
非常好!我多次看到人们认为他们可以使用always @(halfsecflag)
这是灾难的秘诀!
您可以在下面找到我重写的一小段代码。
所有分配都是非阻塞的
<=
halfsecflag
每半秒运行一次代码是必不可少的,所以我把它单独if
放在顶部。我会在整个代码中使用它。所有寄存器都被复位,
COUNT2
和dashflag
。dashflag
设置为 1 但从未设置回 0。我修复了这个问题。我指定了矢量大小。它使代码“Lintproof”。
就这个:
always @(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1'b1)
begin
COUNT2 <= 2'd00;
dashflag <= 1'b0;
end // reset
else if (halfsecflag) // or if (halfsecflag==1'b1)
begin
if (COUNT2==2'd2))
begin
COUNT2 <= 2'd0;
dashflag <=1'b1;
end
else
begin
COUNT2 <= COUNT2+2'd1;
dashflag <=1'b0;
end
end // clocked
end // always
以相同的方式开始修复其余代码。编写一个测试台,在出现问题的波形显示上进行仿真和跟踪。
推荐阅读
- ruby-on-rails - 如何为 Rails 中的嵌套资源编写此条件语句?
- angular - 在使用 Karma/Jasmine 的 Angular 测试中解决“在 afterAll 中抛出一个错误,不可迭代”
- php - 如何使 Html 下拉列表选择的值打印为 CSV?
- laravel - Laravel:array_push 在 collection->each() 迭代器中不起作用
- asp.net-core - 映射布尔时“可为空的对象必须有一个值”?布尔?
- amazon-web-services - AWS RDS - 备份失败时的事件通知
- postgresql - AWS DMS 任务在 CDC 模式下一段时间后失败
- c# - 如果在提交时抛出异常,C# TransactionScope 会回滚吗?
- symfony - 在没有数据库的情况下使用 Symfony 4.4.23,Symfony 更新会导致此问题
- html - 防止页面加载时菜单动画过渡