0
\$\begingroup\$

I'm working on a Verilog project using a FPGA (BEMICROMAX10) and some breadboard components. The project is to make a digital clock in which you can also set the time using the buttons on the FPGA. I realize this verilog code is not the most efficient way to write this but it's how I currently have it set up and the deadline approaches so can't restart. I think I'm almost done so I'm hoping you guys can get me over the last hurdle.

The time from seconds to minutes to hours, is working perfectly when I power it but I can not get the buttons to function to change the minutes and hours manually (while the seconds are running). If you look at line 98 after the large chunk of seconds, I run into the error when I add 'or posedge outm'. I've tried other things but it seems I either get the 'cannot match operands' error or the 'multiple constant drivers' error which I assume is telling me I'm trying to change countmin and counthr with multiple inputs (from clk and btn). I'm really stuck and have no idea where to go from here.

I've just made an edit to drive slow_clk2 with another clock input on the FPGA, and added the outm line for the button, but still no luck.

Thanks for your help.

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

\$\endgroup\$
  • 3
    \$\begingroup\$ always @ (posedge slow_clk2[M-1]) using registers as clocks like this is just asking for trouble. You really, really should rework things to use one clock, and then within that edge-triggered block a condition which enables the register assignment. So basically your huge variety of clocks should instead become enables. \$\endgroup\$ – Chris Stratton May 28 '16 at 8:52
  • \$\begingroup\$ You may have changed one instance of the issue (albeit not the one you mention) but others such as the one quoted in my earlier comment remain. \$\endgroup\$ – Chris Stratton May 28 '16 at 18:34
1
\$\begingroup\$

I don't see where slow_clk2 is deiven, but you should change the code to use only a single clock. I would also move the functional logic all to the top, and keep the segment decode stand-alone at the end.

The behaviour will be clearer if you use this sort of form:

wire tick_1hz = &slow_clk[N-2:0];

always @ (posedge clk)
  if(tick_1hz) begin  
    if (countsec == 8'b00111011) countsec <= 8'h00;  
    else  countsec <= countsec + 8'h01;  
  end

This should drop in without needing to modify the function of your design, and if it doesn't fix the problem (from race conditions), it will at least make the code slightly clearer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.