如何在没有时钟的情况下生成上升沿来控制verilog中的移位寄存器?
首先,让我解释一下我想做什么。我使用的DE0有四个七段显示。我的目标是生成一个滚动显示的文本字符串,该文本字符串基于用户输入。用户有三个对应于A、B和C的按钮 我已经能够创建一个“循环”,在七段显示器上显示文本,但是我很难获取用户输入。我的想法是使用一个9位移位寄存器,它接收用户输入,并将过去的输入向下移位 请不要告诉我,我对verilog还很陌生,我仍然在试图找出在编写代码时如何最好地考虑它。到目前为止,我发现最好从物理硬件的角度对其进行可视化 也就是说,这就是我所想象的: 新输入=>触发器1=>FF2=>FF3=>FF4=>FF5=>FF6=>FF7=>FF8=>放弃旧输入 利用这个想法,我编写了以下代码:如何在没有时钟的情况下生成上升沿来控制verilog中的移位寄存器?,verilog,shift-register,Verilog,Shift Register,首先,让我解释一下我想做什么。我使用的DE0有四个七段显示。我的目标是生成一个滚动显示的文本字符串,该文本字符串基于用户输入。用户有三个对应于A、B和C的按钮 我已经能够创建一个“循环”,在七段显示器上显示文本,但是我很难获取用户输入。我的想法是使用一个9位移位寄存器,它接收用户输入,并将过去的输入向下移位 请不要告诉我,我对verilog还很陌生,我仍然在试图找出在编写代码时如何最好地考虑它。到目前为止,我发现最好从物理硬件的角度对其进行可视化 也就是说,这就是我所想象的: 新输入=>触发器1
wire[1:0] oneFF, twoFF, threeFF, fourFF, fiveFF, sixFF, sevenFF, eightFF;
reg[1:0] change;
wire bA, bB, bC; //Detects change in user input - either 1 or 0
parameter A = 2'b00; parameter B = 2'b01; parameter C = 2'b10;
//They are declared as wires since they really only interconnect portions of
the hardware
FF One(clk, change, oneFF);
FF Two(clk, oneFF, twoFF);
FF Three(clk, twoFF, threeFF);
FF Four(clk, threeFF, fourFF);
FF Five(clk, fourFF, fiveFF);
FF Six(clk, fiveFF, sixFF);
FF Seven(clk, sixFF, sevenFF);
FF Eight(clk, sevenFF, eightFF);
module FF(clk, in, out);
input clk;
input [1:0] in;
output reg [1:0] out;
reg [31:0] count;
always @(posedge clk)
begin
count <= count + 1;
if(count == 50000000) begin
out <= in;
count <= 0;
end
end
endmodule
这就是我遇到的问题。我可以按下一个按钮,但第一个寄存器中的更改将通过链传播。显然,这是因为所有八个寄存器都绑定到同一个时钟。这个时钟是以50mHz的频率运行的,所以它看起来是瞬间发生的。这就是为什么我在模块FF
中的计数器中进行检查,以便确认我的怀疑
为了解决这个问题,我尝试在始终
块中插入一个位“update”,尝试在每个输入处创建一个正边缘,但这不起作用
例如:
reg update;
always @(*)
begin
update = 0;
if(bA) begin
change = A;
update = ~update;
end
if(bB) begin
update = ~update;
change = B;
end
if(bC) begin
change = C;
update = ~update;
end
update = 0;
end
我还将相应地更改模块实例化。如果我将此块更改为非块指定,也会出现这种情况
我想对于这个问题有一个非常简单的解决方案。基本上,我想要的就是这个效果
字符串初始化:
输入:A
下一个输入:B A
而不是
输入:A
下一个输入:B
欢迎任何建设性输入。不要试图从组合逻辑生成边缘或脉冲。你可以用时钟做你想做的事情,所以你应该坚持纯粹的时钟逻辑 如果要根据用户输入更改的时间生成更新选通信号,则存储按钮的先前值,并在按钮更改时生成更新
wire bA;
reg bA_q;
reg update;
always @(posedge clk) begin
bA_q <= bA;
end
always @* begin
if(bA && !bA_q) begin
change = A;
update = 1'b1;
end else begin
update = 1'b0;
change = 0; //this can be anything, just set it so you don't infer a latch
end
end
wire-bA;
注册会计师;
注册号更新;
始终@(posedge clk)开始
不要试图从组合逻辑中产生边缘或脉冲。你可以用时钟做你想做的事情,所以你应该坚持纯粹的时钟逻辑
如果要根据用户输入更改的时间生成更新选通信号,则存储按钮的先前值,并在按钮更改时生成更新
wire bA;
reg bA_q;
reg update;
always @(posedge clk) begin
bA_q <= bA;
end
always @* begin
if(bA && !bA_q) begin
change = A;
update = 1'b1;
end else begin
update = 1'b0;
change = 0; //this can be anything, just set it so you don't infer a latch
end
end
wire-bA;
注册会计师;
注册号更新;
始终@(posedge clk)开始
不要试图从组合逻辑中产生边缘或脉冲。你可以用时钟做你想做的事情,所以你应该坚持纯粹的时钟逻辑
如果要根据用户输入更改的时间生成更新选通信号,则存储按钮的先前值,并在按钮更改时生成更新
wire bA;
reg bA_q;
reg update;
always @(posedge clk) begin
bA_q <= bA;
end
always @* begin
if(bA && !bA_q) begin
change = A;
update = 1'b1;
end else begin
update = 1'b0;
change = 0; //this can be anything, just set it so you don't infer a latch
end
end
wire-bA;
注册会计师;
注册号更新;
始终@(posedge clk)开始
不要试图从组合逻辑中产生边缘或脉冲。你可以用时钟做你想做的事情,所以你应该坚持纯粹的时钟逻辑
如果要根据用户输入更改的时间生成更新选通信号,则存储按钮的先前值,并在按钮更改时生成更新
wire bA;
reg bA_q;
reg update;
always @(posedge clk) begin
bA_q <= bA;
end
always @* begin
if(bA && !bA_q) begin
change = A;
update = 1'b1;
end else begin
update = 1'b0;
change = 0; //this can be anything, just set it so you don't infer a latch
end
end
wire-bA;
注册会计师;
注册号更新;
始终@(posedge clk)开始
谢谢你的建议。出于好奇,我尝试将此方法应用于FSM(这是我几天前发布的另一个问题)。但是,在这种情况下,对按钮进行采样不起作用。相反,我必须使用多个串联触发器来检测一个变化,这触发了一个持续一个时钟周期的信号。在FSM中触发一个状态变化和它在这里的应用有显著区别吗?@Mlagma(bA&&!bA_q)
与您的,只是另一种写作方式bA_q
是另一个触发器,我的回答添加了额外的元稳定性触发器,因为异步按钮事件。这个答案是一致的,没有冲突。谢谢你的建议。出于好奇,我尝试将此方法应用于FSM(这是我几天前发布的另一个问题)。但是,在这种情况下,对按钮进行采样不起作用。相反,我必须使用多个串联触发器来检测一个变化,这触发了一个持续一个时钟周期的信号。在FSM中触发一个状态变化和它在这里的应用有显著区别吗?@Mlagma(bA&&!bA_q)
与您的,只是另一种写作方式bA_q
是另一个触发器,我的回答添加了额外的元稳定性触发器,因为异步按钮事件。这个答案是一致的,没有冲突。谢谢你的建议。出于好奇,我尝试将此方法应用于FSM(这是我几天前发布的另一个问题)。但是,在这种情况下,对按钮进行采样不起作用。相反,我必须使用多个串联触发器来检测一个变化,这触发了一个持续一个时钟周期的信号。在FSM中触发一个状态变化和它在这里的应用有显著区别吗?@Mlagma(bA&&!bA_q)
与您的,只是另一种写作方式bA_q
是另一个触发器,我的回答添加了额外的元稳定性触发器,因为异步按钮事件。这个答案是正确的