2012-05-29 2 views
1

에서 사용자의 입력 (I는의 Quartus II 적이있는을 실행하고 있습니다. 10.1 및 11.0 (나는 모두를 시도했습니다)). 나는 내 인생에 대해 알 수없는 매우 기괴한 버그를 얻고있다.의 Verilog HDL, 나는 현재 내 학교에서 얻은 FPGA와의 Verilog HDL의 프로젝트에 참여하고 FPGA를

나는 점과 대시를 감지 한 다음이 입력에 기초한 HEX 디스플레이의 해당 문자를 출력하는 모스 코드 프로그램을 개발하고있다. 16 진수 디스플레이는 아름답게 작동하지만, 내 UserInput 모듈은 아무 것도하지 않는 것 같습니다!

module UserInput(Clock, reset, in, out); 
input Clock, reset, in; 
output reg [1:0] out; 

wire [2:0] PS; 
reg [2:0] NS; 

parameter NONE = 2'b00, DOT = 2'b01, DASH = 2'b11; //For Output 
parameter UP = 3'b000, SHORT0 = 3'b001, SHORT1 = 3'b010, UP_DOT = 3'b011, LONG = 3'b100, UP_DASH = 3'b101; 

//Active High 
[email protected](PS or in) 
    case (PS) 
     UP: if (in)   NS = SHORT0; 
      else    NS = UP; 

     SHORT0: if (in) NS = SHORT1; 
       else   NS = UP_DOT; 

     SHORT1: if (in) NS = LONG; 
       else   NS = UP_DOT; 

     UP_DOT:     NS = UP; 

     LONG: if (in)  NS = LONG; 
       else   NS = UP_DASH; 

     UP_DASH:   NS = UP; 
    default: NS = 3'bxxx; 
    endcase 

[email protected](PS) 
    case (PS) 
     UP:  out = NONE; 
     SHORT0: out = NONE; 
     SHORT1: out = NONE; 
     UP_DOT: out = DOT; 
     LONG: out = NONE; 
     UP_DASH: out = DASH; 
     default: out = 2'bxx; 
    endcase 

D_FF dff0 (PS[0], NS[0], reset, Clock); 
D_FF dff1 (PS[1], NS[1], reset, Clock); 
D_FF dff2 (PS[2], NS[2], reset, Clock); 

endmodule 

module D_FF (q, d, reset, clk); 
    input d, reset, clk; 
    output reg q; 

    [email protected](posedge clk or posedge reset) 
    begin 
     if (reset) q = 0; 
     else  q = d; 
    end 
endmodule 

모듈의 입력은 FPGA의 KEY입니다. UserInput 모듈이 나타내는 FSM은 t = 0에서 키가 "UP"상태에 있습니다. 그런 다음 입력이 있으면 SHORT0 또는 SHORT1을 통해 이동하고 마지막으로 LONG을 이동합니다. 키가 이러한 상태 중 하나에서 해제되면 해당 중개 UP 상태로 이동하여 "DOT"또는 "DASH"의 출력을 제공합니다. 내 FPGA에이 연결되면

그러나, 나는 아무 것도 얻을 수 없습니다. 테스트 결과, 결코 "UP"상태에서 벗어나지 않는 것으로 보입니다. 내 시뮬레이션조차도 아무것도주지 못합니다. 둘째, 다른 프로젝트 (다른 ​​하나의 프로젝트에서 다른 UserInput 모듈에 연결하는 중)를 연결해 보았습니다. Verilog의 배경에 뭔가 빠져 있는데 실종 됐나요? Simulation Waveform

DFF 0, 1, 2, 비트 0, 1, 2이다 PS : 여기

시뮬레이션 파형의 이미지이다. 시뮬레이션 결과 NS의 표시가 허용되지 않습니다.

+1

? 테스트 벤치 코드를 넣을 수 있습니까? – Tim

+0

네, 맞습니다. 불행히도, 나는 testbench 코드를 작성하는 방법을 모른다. 필자는 알테라 대학 프로그램 시뮬레이터 (Altera University Program Simulator)를 사용하는 방법을 배웠다. 그러나 Altera UP 시뮬레이터로 시뮬레이트하고 적절한 리셋, 클록 및 자극을 제공하면 DFF가 변경되지 않습니다. – cjspook

+0

더 자세한 정보가 없으면 무엇을 말할 지 모르겠습니다. 제 생각에 리셋 극성이 섞여 있지 않다면 거기에있는 것이 효과가 있다고 생각합니다. 만약 당신이 파도를 디버깅하고 있다면 어쩌면 작동하지 않을 때 관련된 신호 (리셋, clk, NS, PS, in)를 보여주는 파도의 스크린 샷을 올릴 수 있을까요? – Tim

답변

2

코드는 (나는 당신이 당신의 코드가 작동하지 않는 듣고 싶은 생각하는) 나에게 나쁜 보인다. 타이밍 문제와 설계 결함의 조합처럼 보입니다. 우리가 무슨 운동을 할 수없는 경우 파형보기를 통해

하자 도보 참조하십시오.

신호가 올라가고, 항상 차단을 트리거합니다. PS가 0이므로 우리는 NS를 1로 설정합니다. 이것은 상승 클럭 에지 시간에 맞지 않으므로 DFF에서 트리거되지 않습니다 (의심 스러웠던 것처럼), 다음 클럭 에지에서 잡힐 염두에 두지 마십시오.

신호가 낮아져 항상 차단을 시작합니다. PS가 0이므로 NS를 0으로 설정합니다. 이것은 상승하는 클럭 에지 시간에 발생하며 DFF에서 캡처됩니다 (예 : NS 신호가 1 우리가 원했던대로).

또한, 누군가가 리셋이 주장하는 동안 주장하고 당신의 플립 플롭에 오류가 있음을 언급했다. 이것은 문제가되지 않습니다. 리셋은 동기식입니다. 그래서 다음 상승 시계에 DFF 그래서 0

로 재설정됩니다 에지 솔루션 무엇을 (그래서 잘하면 당신은 이미이 문제를 해결 한, 나에게 숙제처럼 보이는!) :

그것은처럼 보일 것이다 이 (내가 그것을 시뮬레이션, 그래서 보장하지 않은 경우) :

Module UserInput (clk, reset, in, out); 
input clk, reset, in; 
output [1:0] out; 

// output parameters 
parameter IDLE = 2'b00; 
parameter DOT = 2'b01; 
parameter DASH = 2'b10; 

// FSM states 
parameter LOW = 3'b000; 
parameter SHORT1 = 3'b001; 
parameter SHORT2 = 3'b010; 
parameter LONG = 3'b100; 

reg [2:0] state; 
wire [1:0] next_out; 
wire [2:0] next_state; 

always @(posedge clk) 
begin 
    if (reset) 
    begin 
     out <= IDLE; 
     state <= LOW; 
    end; 
    else 
    begin 
     out <= next_out; 
     state <= next_state; 
    end 
    end if; 
end 

always @(*) 
begin 
    case (state) 
    LOW: 
     next_out = IDLE; 
     next_state = (in? SHORT1 : LOW); 
    SHORT1: 
    begin 
     next_state = (in? SHORT2: LOW); 
     next_out = (in? IDLE : DOT); 
    end; 
    SHORT2: 
     next_state = (in? LONG: LOW); 
     next_out = (in? IDLE : DOT); 
    LONG: 
     next_state = (in? LONG : LOW); 
     next_out = (in? IDLE : DASH); 
    default: 
     // we shouldn't get here!! 
     next_state = LOW; 
     next_out = IDLE; 
    end; 
    end module; 

그래서 여기에 무슨 일이 일어나고 있는지 : 나는이 상당히 명백해야한다 생각합니다. 인 신호가 하이에서 로우로 이동하면 현재 상태 (LONG은 DASH, SHORT1 및 SHORT2는 DOT)로 출력하고, 그렇지 않으면 IDLE을 출력합니다. 인 신호가 높으면 얼마나 오랫동안 높은 지에 따라 상태를 옮기고 싶습니다.

시뮬레이션에 영향을 미치지 않지만 FPGA에서 거의 영향을 미치지 않는이 코드에는 오류가 있습니다. 외부 소스에서 입력을받는 경우 직렬 (?) 입력을 통해 버퍼링해야합니다.)의 플립 플롭을 사용하여 준 안정 문제를 방지합니다. 이는 in 신호를 캡처하기 위해 일련의 D 플립 플롭을 추가 한 다음이 "정리 된"buffered_in을 UserInput에 전달하여 수정할 수 있습니다.

예 : 당신이 * 자극에 *, 당신은 당신이 적절한 리셋, 시계를 적용하고 말을하는 시뮬레이션 작업, 그리고이 아니라고, 아직 DFF들은 절대 변하지 않을

module in_buffer (clk, reset, in, out); 
input clk, reset, in; 
output out; 

reg buf1, buf2; 

always @ (posedge clk) 
begin 
    if (reset) 
    begin 
     out <= 0; 
     buf1 <= 0; 
     buf2 <= 0; 
    end 
    else 
     out <= buf2; 
     buf2 <= buf1; 
     buf1 <= in; 
    end 
end