首先,让我解释一下我要做什么。我正在使用具有四个七段显示器的 DE0。我的目标是生成一个在显示器上滚动的文本字符串,并且文本字符串基于用户输入。用户有三个按钮,分别对应 A、B 和 C。
我已经能够创建一个在七段显示器上显示文本的“循环”,但我在获取用户输入时遇到了困难。我的想法是使用一个 9 位移位寄存器,它可以接受用户输入并将过去的输入沿链向下移动。
请不要说我对 verilog 很陌生,而且我仍在试图弄清楚在编写代码时如何最好地考虑它。到目前为止,我发现最好在物理硬件方面对其进行可视化。
也就是说,这就是我正在想象的:
新输入 => Flip-Flop1 => 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
然后我写了一个模块来检测change
寄存器的输入:
always @(*)
begin
if(bA) begin
change = A;
end
if(bB) begin
change = B;
end
if(bC) begin
change = C;
end
end
这就是我遇到问题的地方。我可以按下一个按钮,但第一个寄存器中的更改将通过链传播。显然,这是因为所有八个寄存器都绑定到同一个时钟。这个时钟以 50mHz 的频率运行,所以它似乎是立即发生的。这就是为什么我通过一个柜台module FF
来确认我的怀疑。
为了解决这个问题,我尝试在always
块中添加一个位“更新”,以尝试在每个输入处创建一个正边缘,但这不起作用。
例如:
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 _ _ _ _ ...
下一个输入:BA _ _ _ ...
代替
输入: AAAA ...
下一个输入:BBBBB ...
任何建设性的意见表示赞赏。