如何在没有时钟的情况下生成上升沿来控制verilog中的移位寄存器?

如何在没有时钟的情况下生成上升沿来控制verilog中的移位寄存器?,verilog,shift-register,Verilog,Shift Register,首先,让我解释一下我想做什么。我使用的DE0有四个七段显示。我的目标是生成一个滚动显示的文本字符串,该文本字符串基于用户输入。用户有三个对应于A、B和C的按钮 我已经能够创建一个“循环”,在七段显示器上显示文本,但是我很难获取用户输入。我的想法是使用一个9位移位寄存器,它接收用户输入,并将过去的输入向下移位 请不要告诉我,我对verilog还很陌生,我仍然在试图找出在编写代码时如何最好地考虑它。到目前为止,我发现最好从物理硬件的角度对其进行可视化 也就是说,这就是我所想象的: 新输入=>触发器1

首先,让我解释一下我想做什么。我使用的DE0有四个七段显示。我的目标是生成一个滚动显示的文本字符串,该文本字符串基于用户输入。用户有三个对应于A、B和C的按钮

我已经能够创建一个“循环”,在七段显示器上显示文本,但是我很难获取用户输入。我的想法是使用一个9位移位寄存器,它接收用户输入,并将过去的输入向下移位

请不要告诉我,我对verilog还很陌生,我仍然在试图找出在编写代码时如何最好地考虑它。到目前为止,我发现最好从物理硬件的角度对其进行可视化

也就是说,这就是我所想象的:

新输入=>触发器1=>FF2=>FF3=>FF4=>FF5=>FF6=>FF7=>FF8=>放弃旧输入

利用这个想法,我编写了以下代码:

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
是另一个触发器,我的回答添加了额外的元稳定性触发器,因为异步按钮事件。这个答案是正确的