2017-04-26 4 views
0

저는 Verilog로 자동 판매기를 만들고 있습니다. FPGA 보드에는 코인 삽입 기의 역할을하는 버튼이 하나 있으며 버튼을 누를 때마다 사용자가 소비 할 수있는 총량에 '분기'가 추가되고 왼쪽 및 오른쪽 7 세그먼트 디스플레이에 총계가 표시됩니다.Verilog에서 버튼 클릭 수 유지

Ex. 첫 번째 버튼 푸시 : 25 센트 두 번째 버튼 푸시 : 50 센트 세 번째 버튼 푸시 : 75 센트 네 번째 버튼 푸시 : $ 1.00 (7 세그먼트 디스플레이에서 10). 네 번째 버튼을 누른 후에 증가하지 않습니다.

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 

가 나는 버튼 클릭의 수를 유지하는 방법에 갇히지하고있다. 나는 7 개의 세그먼트 전시에 첫번째 가치를 볼 수있다, 그러나 총 동전을 증가하는 방법에 관해서는 확실하지 않다. 나는 이것에 대한 정보를 찾지 못했습니다.

+1

상태는 레지스터에 보관해야합니다. 이것은 플립 플롭, 즉 일반적으로 "posedge clk"을 업데이트하는 코드가 필요합니다. – JohanL

+0

@JohanL 이렇게하면 어떨까요? '항상 @ (posedge 시계) \t 시작 \t 상태 = next_state; \t end ' – grimes88

+0

글쎄, 저장된 상태는 본질적으로'totalChange'이므로, 저장해야 할 것이 있습니다. – JohanL

답변

0

내가 이해 한 바에 따르면 버튼 누름을 추적하기 위해 포화 카운터가 필요합니다.

input clock; 

그리고 당신이 경우에, 알려진 값에 제로 카운터를 초기화하는 리셋 신호가 필요합니다 :

는 계산하려면 시스템에 시계를 필요

input reset; 

그리고 카운터합니다 (state 변수에 해당 나를 그냥 num_push를 호출하자) :

reg [2:0] num_push; 

이 포화 카운터는이 방법을 지정할 수 있습니다 :이와 카운터에 합성됩니다

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 

당신의 FPGA에 카운트 활성화하고는 quarterIn == 1'b1 && num_push != 3'b100와 동일합니다 수 있습니다. 다시 시작하려면 reset을 누르십시오.


이제 우리는 이것을 FPGA에 넣기 전에 해결해야 할 몇 가지 문제가 있습니다. 우선, quarterIn 준 안정성에 대한 동기화 할 필요가있다 : 우리는 직접에만 quarterIn_sync 설계에 결코 quarterIn를 사용해야합니다

reg quarterIn_f; 
reg quarterIn_sync; 

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

. reset 신호에 대해서도 동일한 작업을 수행해야합니다.

둘째로, 키에서 오는 신호는 디 바운스되어야합니다. 디 바운싱 (debouncing) 자체는 전체적인 주제이므로 당분간 건너 뛸 것입니다. (

또 다른 한가지는 온보드 클럭 생성기 회로에서 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 

을 그리고 우리는 완료!