2016-05-28 13 views
1

Ich arbeite an einem Verilog-Projekt mit einem FPGA (BEMICROMAX10) und einigen Steckbrettkomponenten. Das Projekt besteht darin, eine digitale Uhr zu erstellen, in der Sie die Zeit auch mit den Tasten auf dem FPGA einstellen können. Ich bin mir bewusst, dass dieser Verilog-Code nicht der effizienteste Weg ist, um dies zu schreiben, aber ich habe es gerade eingerichtet.Verilog "kann Operanden nicht zuordnen" & "mehrere konstante Treiber"

Die Zeit von Sekunden zu Minuten zu Stunden, funktioniert perfekt, wenn ich es einschalte, aber ich kann die Tasten nicht erreichen, um die Minuten und Stunden manuell zu ändern (während die Sekunden laufen). Wenn Sie nach einem großen Teil der Sekunden auf Zeile 98 schauen, stoße ich auf den Fehler, wenn ich 'or posegege outm' hinzufüge. Ich habe andere Dinge ausprobiert, aber es scheint, dass ich entweder den Fehler "Kann nicht übereinstimmen Operanden" oder den Fehler "Mehrere konstante Treiber" bekomme, der mir sagt, ich versuche counmin und counthr mit mehreren Eingaben zu ändern (von clk und btn). Ich bin wirklich fest und habe keine Ahnung, wohin ich von hier aus gehen soll.

Ich habe gerade einen Schnitt gemacht, um slow_clk2 mit einem anderen Takteingang auf dem FPGA zu fahren, und die Outm-Linie für den Knopf hinzugefügt, aber immer noch kein Glück.

module digital_clock(clk, clk2, minbtn, hrbtn, segsec, segmin, seghr); 
input clk, clk2, minbtn, hrbtn; 
output [13:0] segsec; 
output [13:0] segmin; 
output [13:0] seghr; 

parameter N = 25; 
reg [N-1:0] slow_clk = 0; 
reg [7:0] countsec = 0, countmin = 0, counthr = 8'h1; 

parameter M = 13; 
reg [M-1:0] slow_clk2 = 0; 
reg [7:0] delay = 0; 
reg [7:0] delay2 = 0; 
wire outm, outh; 

always @ (posedge clk) 
    slow_clk <= slow_clk + 1'b1; 

always @ (posedge clk2) 
    slow_clk2 <= slow_clk2 + 1; 

always @ (posedge slow_clk2[M-1]) 
    begin 
    delay <= delay << 1;  
    delay2 <= delay2 << 1; 
    delay[0] <= ~minbtn; 
    delay2[0] <= ~hrbtn; 
    end 

assign outm = delay[7] & delay[6] & delay[5] & delay[4] & delay[3] & delay[2] & delay[1] & delay[0]; 

assign outh = delay2[7] & delay2[6] & delay2[5] & delay2[4] & delay2[3] & delay2[2] & delay2[1] & delay2[0]; 

always @ (posedge slow_clk[N-1]) 
    if (countsec == 8'b00111011) countsec <= 8'b0; 
    else countsec <= countsec + 8'b1; 

assign segsec = (countsec == 8'h0) ? 16'b01111110111111: 
    (countsec == 8'h1) ? 16'b01111110000110: //1  0000110  0111111 
    (countsec == 8'h2) ? 16'b01111111011011: //2  1011011 
    (countsec == 8'h3) ? 16'b01111111001111: //3  1001111 
    (countsec == 8'h4) ? 16'b01111111100110: //4  1100110 
    (countsec == 8'h5) ? 16'b01111111101101: //5  1101101 
    (countsec == 8'h6) ? 16'b01111111111101: //6  1111101 
    (countsec == 8'h7) ? 16'b01111110000111: //7  0000111 
    (countsec == 8'h8) ? 16'b01111111111111: //8  1111111 
    (countsec == 8'h9) ? 16'b01111111101111: //9  1101111 
    (countsec == 8'ha) ? 16'b00001100111111: //10 
    (countsec == 8'hb) ? 16'b00001100000110://11 
    (countsec == 8'hc) ? 16'b00001101011011://12 
    (countsec == 8'hd) ? 16'b00001101001111://13 
    (countsec == 8'he) ? 16'b00001101100110: //14 
    (countsec == 8'hf) ? 16'b00001101101101: //15 
    (countsec == 8'h10) ? 16'b00001101111101://16 
    (countsec == 8'h11) ? 16'b00001100000111://17 
    (countsec == 8'h12) ? 16'b00001101111111://18 
    (countsec == 8'h13) ? 16'b00001101101111://19 
    (countsec == 8'h14) ? 16'b10110110111111://20 
    (countsec == 8'h15) ? 16'b10110110000110://21 
    (countsec == 8'h16) ? 16'b10110111011011://22 
    (countsec == 8'h17) ? 16'b10110111001111://23 
    (countsec == 8'h18) ? 16'b10110111100110://24 
    (countsec == 8'h19) ? 16'b10110111101101://25 
    (countsec == 8'h1a) ? 16'b10110111111101://26 
    (countsec == 8'h1b) ? 16'b10110110000111://27 
    (countsec == 8'h1c) ? 16'b10110111111111://28 
    (countsec == 8'h1d) ? 16'b10110111101111://29 
    (countsec == 8'h1e) ? 16'b10011110111111://30 
    (countsec == 8'h1f) ? 16'b10011110000110://31 
    (countsec == 8'h20) ? 16'b10011111011011://32 
    (countsec == 8'h21) ? 16'b10011111001111://33 
    (countsec == 8'h22) ? 16'b10011111100110://34 
    (countsec == 8'h23) ? 16'b10011111101101://35 
    (countsec == 8'h24) ? 16'b10011111111101://36 
    (countsec == 8'h25) ? 16'b10011110000111://37 
    (countsec == 8'h26) ? 16'b10011111111111://38 
    (countsec == 8'h27) ? 16'b10011111101111://39 
    (countsec == 8'h28) ? 16'b11001100111111://40 
    (countsec == 8'h29) ? 16'b11001100000110://41 
    (countsec == 8'h2a) ? 16'b11001101011011://42 
    (countsec == 8'h2b) ? 16'b11001101001111://43 
    (countsec == 8'h2c) ? 16'b11001101100110://44 
    (countsec == 8'h2d) ? 16'b11001101101101://45 
    (countsec == 8'h2e) ? 16'b11001101111101://46 
    (countsec == 8'h2f) ? 16'b11001100000111://47 
    (countsec == 8'h30) ? 16'b11001101111111://48 
    (countsec == 8'h31) ? 16'b11001101101111://49 
    (countsec == 8'h32) ? 16'b11011010111111://50 
    (countsec == 8'h33) ? 16'b11011010000110://51 
    (countsec == 8'h34) ? 16'b11011011011011://52 
    (countsec == 8'h35) ? 16'b11011011001111://53 
    (countsec == 8'h36) ? 16'b11011011100110://54 
    (countsec == 8'h37) ? 16'b11011011101101://55 
    (countsec == 8'h38) ? 16'b11011011111101://56 
    (countsec == 8'h39) ? 16'b11011010000111://57 
    (countsec == 8'h3a) ? 16'b11011011111111://58 
    (countsec == 8'h3b) ? 16'b11011011101111://59 
    16'b01111110111111; 

always @ (posedge slow_clk[N-1] or posedge outm) 
if (outm) 
    countmin <= countmin + 8'b1; 
    else if (countmin == 8'b00111011 && countsec == 8'b00111011) countmin <= 8'b0; 
    else if (countmin != 00111011 && countsec == 8'b00111011) countmin <= countmin + 8'b1; 
    else countmin <= countmin; 

assign segmin = (countmin == 8'h0) ? 16'b01111110111111: 
    (countmin == 8'h1) ? 16'b01111110000110: //1  0000110  0111111 
    (countmin == 8'h2) ? 16'b01111111011011: //2  1011011 
    (countmin == 8'h3) ? 16'b01111111001111: //3  1001111 
    (countmin == 8'h4) ? 16'b01111111100110: //4  1100110 
    (countmin == 8'h5) ? 16'b01111111101101: //5  1101101 
    (countmin == 8'h6) ? 16'b01111111111101: //6  1111101 
    (countmin == 8'h7) ? 16'b01111110000111: //7  0000111 
    (countmin == 8'h8) ? 16'b01111111111111: //8  1111111 
    (countmin == 8'h9) ? 16'b01111111101111: //9  1101111 
    (countmin == 8'ha) ? 16'b00001100111111: //10 
    (countmin == 8'hb) ? 16'b00001100000110: //11 
    (countmin == 8'hc) ? 16'b00001101011011: //12 
    (countmin == 8'hd) ? 16'b00001101001111: //13 
    (countmin == 8'he) ? 16'b00001101100110: //14 
    (countmin == 8'hf) ? 16'b00001101101101: //15 
    (countmin == 8'h10) ? 16'b00001101111101://16 
    (countmin == 8'h11) ? 16'b00001100000111://17 
    (countmin == 8'h12) ? 16'b00001101111111://18 
    (countmin == 8'h13) ? 16'b00001101101111://19 
    (countmin == 8'h14) ? 16'b10110110111111://20 
    (countmin == 8'h15) ? 16'b10110110000110://21 
    (countmin == 8'h16) ? 16'b10110111011011://22 
    (countmin == 8'h17) ? 16'b10110111001111://23 
    (countmin == 8'h18) ? 16'b10110111100110://24 
    (countmin == 8'h19) ? 16'b10110111101101://25 
    (countmin == 8'h1a) ? 16'b10110111111101://26 
    (countmin == 8'h1b) ? 16'b10110110000111://27 
    (countmin == 8'h1c) ? 16'b10110111111111://28 
    (countmin == 8'h1d) ? 16'b10110111101111://29 
    (countmin == 8'h1e) ? 16'b10011110111111://30 
    (countmin == 8'h1f) ? 16'b10011110000110://31 
    (countmin == 8'h20) ? 16'b10011111011011://32 
    (countmin == 8'h21) ? 16'b10011111001111://33 
    (countmin == 8'h22) ? 16'b10011111100110://34 
    (countmin == 8'h23) ? 16'b10011111101101://35 
    (countmin == 8'h24) ? 16'b10011111111101://36 
    (countmin == 8'h25) ? 16'b10011110000111://37 
    (countmin == 8'h26) ? 16'b10011111111111://38 
    (countmin == 8'h27) ? 16'b10011111101111://39 
    (countmin == 8'h28) ? 16'b11001100111111://40 
    (countmin == 8'h29) ? 16'b11001100000110://41 
    (countmin == 8'h2a) ? 16'b11001101011011://42 
    (countmin == 8'h2b) ? 16'b11001101001111://43 
    (countmin == 8'h2c) ? 16'b11001101100110://44 
    (countmin == 8'h2d) ? 16'b11001101101101://45 
    (countmin == 8'h2e) ? 16'b11001101111101://46 
    (countmin == 8'h2f) ? 16'b11001100000111://47 
    (countmin == 8'h30) ? 16'b11001101111111://48 
    (countmin == 8'h31) ? 16'b11001101101111://49 
    (countmin == 8'h32) ? 16'b11011010111111://50 
    (countmin == 8'h33) ? 16'b11011010000110://51 
    (countmin == 8'h34) ? 16'b11011011011011://52 
    (countmin == 8'h35) ? 16'b11011011001111://53 
    (countmin == 8'h36) ? 16'b11011011100110://54 
    (countmin == 8'h37) ? 16'b11011011101101://55 
    (countmin == 8'h38) ? 16'b11011011111101://56 
    (countmin == 8'h39) ? 16'b11011010000111://57 
    (countmin == 8'h3a) ? 16'b11011011111111://58 
    (countmin == 8'h3b) ? 16'b11011011101111://59 
    16'b11011010111111; 

always @ (posedge slow_clk[N-1] or posedge outh) 
    if (outh) begin 
     counthr <= counthr + 8'b1; 
     end 
    else if(counthr != 8'b00001100 && countmin == 8'b00111011 && countsec == 8'b00111011) counthr <= counthr + 8'b1; 
    else if (counthr == 8'b00001100 && countmin == 8'b00111011 && countsec == 8'b00111011) counthr <= 8'b1; 
    else counthr <= counthr; 

assign seghr = (counthr == 8'h1) ? 16'b01111110000110: //1  0000110  0111111 
    (counthr == 8'h2) ? 16'b01111111011011: //2  1011011 
    (counthr == 8'h3) ? 16'b01111111001111: //3  1001111 
    (counthr == 8'h4) ? 16'b01111111100110: //4  1100110 
    (counthr == 8'h5) ? 16'b01111111101101: //5  1101101 
    (counthr == 8'h6) ? 16'b01111111111101: //6  1111101 
    (counthr == 8'h7) ? 16'b01111110000111: //7  0000111 
    (counthr == 8'h8) ? 16'b01111111111111: //8  1111111 
    (counthr == 8'h9) ? 16'b01111111101111: //9  1101111 
    (counthr == 8'ha) ? 16'b00001100111111: //10 
    (counthr == 8'hb) ? 16'b00001100000110: //11 
    (counthr == 8'hc) ? 16'b00001101011011: //12 
    16'b01111110000110; 
endmodule 
+0

Diese Zeile 'always @ (posedge slow_clk [N-1] oder posedge outm)' ist legal Verilog, aber nicht synthetisieren. Denken Sie darüber nach: Welche Hardware können Sie entwerfen, die sowohl auf eine Taktflanke als auch auf eine Flanke eines anderen Signals reagiert? Wenn Sie eine Flanke an einem anderen Signal erkennen möchten, müssen Sie einen [_synchronous edge detector_] (https://www.doulos.com/knowhow/fpga/synchronisation/) entwerfen (einen Link zur Website meiner Firma). –

Antwort

2

Ihr Design ist nicht synchron mit multiple clocks domains (clk, slow_clk2 [M-1] und slow_clk [N-1]). Ich denke, Sie wollen clock domains crossing in Ihrem Design nicht verwalten. Liege ich falsch ?

Alle Prozesse in Ihrem Design (immer @) sollten mit CLK-Signal umschalten. Zur Lösung Ihres Problems sollten Sie die ansteigende Flanke des slow_clk2 erfassen [M-1] und slow_clk [M-1] wie folgt

always @ (posedge clk) 
begin 
    if(slow_clk2_old != slow_clk2[M-1] and slow_clk2[M-1] == 1'b1) 
     slow_clk2_rise <= 1'b1; 
    else 
     slow_clk2_rise <= 1'b0; 

    slow_clk2_old <= slow_clk2[M-1] 
end 

und verwenden Sie Ihre Signal slow_clk2_rise wie es (statt posedge ...):

always @ (posedge clk) // all your synchronous process must toggle on clk 
begin 
if (slow_clk2_rise) 
    begin 
     delay <= delay << 1;  
     delay2 <= delay2 << 1; 
     delay[0] <= ~minbtn; 
     delay2[0] <= ~hrbtn; 
    end 
end 

Machen Sie dasselbe mit slow_clk [M-1]