2017-04-26 68 views
0

我正在verilog中创建自动售货机。 FPGA板上有一个按钮用作硬币插入器,每次按下按钮时,它将为用户可花费的总金额增加一个“四分之一”,并将总数显示在左侧和右侧七段显示器上。在Verilog中保持按钮点击数

例。 第一个按钮推动:25美分 第二个按钮推动:50美分 第三个按钮推动:75美分 第四个按钮推动:$ 1.00(七段显示10个)。 按下第4个按钮后不会增加。

input quarterIn, 
output reg [4:0] state, 
output reg [4:0] next_state, 
output reg totalChange, 
output reg [7:0] RSSD, 
output reg [7:0] LSSD 
); 

/***coin implementation***/ 
parameter 
    c0 = 0, 
    c1 = 1, 
    c2 = 2, 
    c3 = 3, 
    c4 = 4; 

always @(posedge clock) begin state = next_state; end

always @ (quarterIn or totalChange) 
begin 
    case(totalChange) 
    0: begin if(quarterIn == 1) totalChange = 1; state = c1; end 
    1: begin if(quarterIn == 1) totalChange = 2; state = c2; end 
    2: begin if(quarterIn == 1) totalChange = 3; state = c3; end 
    3: begin if(quarterIn == 1) totalChange = 4; state = c4; end 
    4: begin if(quarterIn == 1) totalChange = 4; state = c4; end 
    endcase 
end 

我被陷在如何保持按键的点击次数。我可以看到七段显示器上的第一个值,但我不确定如何增加总硬币。我无法从自己的研究中找到任何有关这方面的信息。

+1

各州必须保存在登记册中。这需要触发器,即通常在“posedge clk”上更新的代码。 – JohanL

+0

@JohanL所以这样的事情? 'always @(posedge clock) \t begin \t state = next_state; \t end' – grimes88

+0

那么,你的存储状态基本上是'totalChange',所以这就是需要存储的内容。 – JohanL

回答

0

从我的理解,你需要一个饱和计数器来跟踪按钮按下。

为了计算,你需要一个时钟系统:

input clock; 

你还需要一个复位信号,在这种情况下,计数器初始化为已知值,零:

input reset; 

,计数器(相当于state变量,让我只是把它num_push):

reg [2:0] num_push; 

的饱和计数器可以指定这样说:在你的FPGA

always @(posedge clock) begin 
    if (reset) begin      // Active high, synchronous reset 
     num_push <= 3'b0; 
    end else begin 
     if (quarterIn == 1'b1 && num_push != 3'b100) begin 
      num_push <= num_push + 3'b1; 
     end 
    end 
end 

这将合成与一个计数器计数启用和启用将等于quarterIn == 1'b1 && num_push != 3'b100。您可以按reset重新开始。


现在,在我们把它放在FPGA上之前,有几个问题需要解决。首先,quarterIn需要被同步亚稳态:

reg quarterIn_f; 
reg quarterIn_sync; 

always @(posedge clock) begin 
    quarterIn_f <= quarterIn; 
    quarterIn_sync <= quarterIn_f; 
end 

我们应该直接使用在设计中只quarterIn_sync永不quarterIn。您也应该对reset信号也一样。

其次,来自按键的信号需要被消除。反弹本身就是一个完整的话题,所以我暂时跳过它:(

另一件事是,clock需要从板载时钟发生器电路拉,这个时钟将运行在几个MHz典型的按键持续时间约为500ms,这意味着我们的计数器将在一次按键中采样几十万按键。为了避免这种情况,我们应该算边缘quarterIn_sync,而不是水平:

wire quarterIn_edge; 
req quarterIn_sync_f; 

always @(posedge clock) begin 
    if (reset) begin 
     quarterIn_sync_f <= 1'b0; 
    end else begin 
     quarterIn_sync_f <= quarterIn_sync; 
    end 
end 

assign quarterIn_edge = quarterIn_sync & ~quarterIn_sync_f; // Detects rising edge 

现在,quarterIn_edge更换quarterIn在饱和计数器代码:

always @(posedge clock) begin 
    if (reset) begin 
     num_push <= 3'b0; 
    end else begin 
     if (quarterIn_edge == 1'b1 && num_push != 3'b100) begin 
      num_push <= num_push + 3'b1; 
     end 
    end 
end 

,我们就大功告成了!

相关问题