2017-06-07 3 views
1

Ich bin neu in Verilog und HDL.
Ich möchte einen N-Frequenzteiler implementieren,
die zählen Tick-Ticks (pos und neg) und starten Sie den Zählmechanismus von der ersten steigenden Flanke des Eingangs clk.
Zusätzlich muss der clk-Teiler synchrone rst_n unterstützen.vermeiden Sperren in frequencny Teiler mit Fsm - Verilog

Ich bin mit Altera Quartus und dem folgenden Code

module clk_divider_fsm 
 
(
 
\t in_clk, 
 
\t rst_n, 
 
\t out_clk 
 
); 
 

 
input in_clk, rst_n; 
 
output out_clk; 
 

 
parameter prescaler = 10; 
 
parameter BIT_DEPTH = `CLOG2(prescaler); 
 
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10; 
 
parameter CNT_RESET = {BIT_DEPTH{1'b0}}; 
 
//parameter CNT_FIRST = {BIT_DEPTH-1{1'b0}, 1'b1}; 
 
reg [1:0] ps, ns; 
 
reg out_change; 
 
reg out; 
 
reg [BIT_DEPTH:0] cnt; 
 

 
initial 
 
begin 
 
\t ps = S0; 
 
\t ns = S0; 
 
\t cnt = CNT_RESET; 
 
\t out_change = 1'b0; 
 
\t out = 1'b0; 
 
end 
 

 
always @ (in_clk) 
 
begin 
 
\t if(!rst_n) 
 
\t \t ps = S0; 
 
\t else 
 
\t \t ps = ns; 
 
// \t begin 
 
// \t \t if(ns != ps) 
 
// \t \t \t ps = ns; 
 
// \t end 
 
end 
 

 
always @ (in_clk) 
 
begin 
 
\t case(ps) 
 
\t \t S0: begin 
 
\t \t \t if(in_clk === 1'b1) 
 
\t \t \t begin 
 
\t \t \t \t out_change <= 1'b1; 
 
\t \t \t \t ns <= S1; 
 
\t \t \t \t cnt <= CNT_RESET + 1'b1; 
 
\t \t \t end 
 
\t \t \t else 
 
\t \t \t begin 
 
\t \t \t \t out_change <= 1'b0; 
 
\t \t \t \t cnt <= CNT_RESET; 
 
\t \t \t \t ns <= S0; 
 
\t \t \t end 
 
\t \t end 
 
\t \t S1: begin 
 
\t \t \t if(in_clk === 1'b0) 
 
\t \t \t begin 
 
\t \t \t \t if(cnt == prescaler) 
 
\t \t \t \t begin 
 
\t \t \t \t \t cnt <= CNT_RESET + 1'b1; 
 
\t \t \t \t \t out_change <= 1'b1; 
 
\t \t \t \t \t ns <= S2; 
 
\t \t \t \t end 
 
\t \t \t \t else 
 
\t \t \t \t begin 
 
\t \t \t \t \t cnt <= cnt + 1'b1; 
 
\t \t \t \t \t out_change <= 1'b0; 
 
\t \t \t \t \t ns <= S2; 
 
\t \t \t \t end 
 
\t \t \t end 
 
\t \t \t else 
 
\t \t \t begin 
 
\t \t \t \t out_change = 1'b0; 
 
\t \t \t \t ns = S1; 
 
\t \t \t \t cnt <= cnt; 
 
\t \t \t end 
 
\t \t end 
 
\t \t 
 
\t \t S2: begin 
 
\t \t \t if(in_clk == 1'b1) 
 
\t \t \t begin 
 
\t \t \t \t if(cnt == prescaler) 
 
\t \t \t \t begin 
 
\t \t \t \t \t cnt <= CNT_RESET + 1'b1; 
 
\t \t \t \t \t out_change <= 1'b1; 
 
\t \t \t \t \t ns <= S1; 
 
\t \t \t \t end 
 
\t \t \t \t else 
 
\t \t \t \t begin 
 
\t \t \t \t \t cnt <= cnt + 1'b1; 
 
\t \t \t \t \t out_change <= 1'b0; 
 
\t \t \t \t \t ns <= S1; 
 
\t \t \t \t end 
 
\t \t \t end 
 
\t \t \t else 
 
\t \t \t begin 
 
\t \t \t \t out_change = 1'b0; 
 
\t \t \t \t ns = S2; 
 
\t \t \t \t cnt <= cnt; 
 
\t \t \t end 
 
\t \t end 
 
\t \t default: begin 
 
\t \t \t out_change <= 1'b0; 
 
\t \t \t cnt <= CNT_RESET; 
 
\t \t \t ns <= S0; 
 
\t \t end 
 
\t endcase 
 
\t 
 
\t if(!rst_n) 
 
\t begin 
 
\t \t ns <= S0; 
 
\t \t cnt <= CNT_RESET; 
 
\t end 
 
end 
 

 
always @ (posedge out_change or negedge rst_n) 
 
begin 
 
\t if(!rst_n) 
 
\t \t out <= 1'b0; 
 
\t else 
 
\t \t out <= ~out; 
 
end 
 

 

 
assign out_clk = (prescaler == 1) ? (in_clk & rst_n) : out; 
 

 
endmodule

Nach der Synthese I erhalten Warnungen über Verriegelungen für cnt Register verwendet.
Was mache ich falsch?

Können Sie mir Tipps für gute Praktiken geben, um solche Fälle in der Zukunft zu vermeiden, oder elegantere Möglichkeiten, diese Art von RTL zu implementieren?

dank

Antwort

1

Wenn Sie Sie können das nicht synchron sein wollen. Sie müssen die Werte auf derselben Ebene von in_clk ändern. Aber im Allgemeinen verwenden wir PLL/DCM, um den Takt zu teilen. Clock folgt dem speziellen Routing in FPGA mit speziellen Puffern.

[Bearbeiten]

always @ (in_clk) 

Diese Riegel synthetisieren. Wenn Sie nicht latch (und synchron sein wollen) müssen Sie alle Ihre Prozess (immer @) mit der gleichen posedge der Uhr auslösen. In Ihrem Fall mit dem gleichen posedge von IN_CLK:

always @ (posedge in_clk) 

Siehe Synthesizing Latches

+0

vielen Dank für Ihre Antwort. Ich versuche, einen einfachen Taktteiler für Lernzwecke zu implementieren. Warum gibt es Verriegelungen mit dem obigen Design? – vintox

+0

Es gibt Zwischenspeicher, weil Sie nicht vollständig synchron sind. – FabienM

+0

Die Latches werden für Cnt-Register nicht für Out- oder Out_change-Register verwendet. Warum beeinflusst der Mechanismus out_change den Zähler des Zustandsautomaten? – vintox