Verilog multiple drivers

10,308

Solution 1

Just to add to mcleod_ideafix's answer you have this block:

always @(posedge Clock) begin
  if (Clear) begin
    BCD1 <= 0;
    BCD0 <= 0;
    end
end

Which implies a synchronous clear, I am not sure if that is your intention as typically you would have an asynchronous clear for you flip-flops in ASIC design, or set initial state for FPGA.

For a flip-flop with an asynchronous active-high clear

always @(posedge clock or posedge clear) begin
  if (clear) begin
    BCD1 <= 'b0;  //NB: defined widths
    BCD0 <= 'b0;
  end
  else
    // normal logic
  end
end

It is more typical to use active-low resets:

always @(posedge clock or negedge clear_n) begin
  if (~clear_n) begin
    BCD1 <= 'b0;  //NB: defined widths
    BCD0 <= 'b0;
  end
  else
    if (up == 1'b1) begin
      // up logic
    end
    else if (down == 1'b1) begin
      // down logic
    end
    else begin 
      // nothing to see here
    end
  end
end

Doing comparisons with == 1'b1 means you will get a width mismatch warning instead of weird behaviour if the LHS (left hand side) is wider than 1 bit.

I also noticed that you have:

output [3:0] BCD1_1, BCD0_0 );
reg [3:0] BCD1, BCD0;
assign BCD1_1 = BCD1;
assign BCD0_0 = BCD0;

You just needed to do the following to have reg's as outputs:

output reg [3:0] BCD1, BCD0

Although I find the following much clearer:

output reg [3:0] BCD1,
output reg [3:0] BCD0

Solution 2

You cannot modify BCD from different always blocks. Any modification should be perfomed in only one always. Something like:

module BCDcountmod(
  input Clock, Clear, up, down,
  output [3:0] BCD1_1, BCD0_0 );
  reg [3:0] BCD1, BCD0;
//reg [3:0] BCD1_1, BCD0_0;

  assign BCD1_1 = BCD1;
  assign BCD0_0 = BCD0;  

  always @(posedge Clock) begin
    //---- IS IT CLEAR? --------------
    if (Clear) begin
      BCD1 <= 0;
      BCD0 <= 0;
    end
    //---- IS IT UP? --------------
    else if (up) then begin
      if (BCD0 == 4'b1001) begin
        BCD0 <= 0;
        if (BCD1 == 4'b1001)
          BCD1 <= 0;
        else
          BCD1 <= BCD1 + 1;
      end
    end
    //---- IS IT DOWN? --------------
    else if (down) begin
      if (BCD0 == 4'b0000) begin
        BCD0 <= 4'b1001;
        if (BCD1 == 4'b1001)
          BCD1 <= 4'b1001;
        else
          BCD1 <= BCD1 - 1;
      end
      else
        BCD0 <= BCD0 - 1;
    end
  end
endmodule
Share:
10,308
user3110542
Author by

user3110542

Updated on June 04, 2022

Comments

  • user3110542
    user3110542 almost 2 years

    I'm trying to make BCD Counter using Verilog that will be connected to 7-segment decoder.
    After I synthesize it, the error occured like this:

    Multi-source in Unit <BCDcountmod> on signal <BCD0<3>>; this signal is connected to multiple drivers.>**And more.....

    ***Any solution?*
    (Here's my code below)

    module BCDcountmod(
      input Clock, Clear, up, down,
      output [3:0] BCD1_1, BCD0_0 );
    reg [3:0] BCD1, BCD0;
    //reg [3:0] BCD1_1, BCD0_0;
    always @(posedge Clock) begin
      if (Clear) begin
        BCD1 <= 0;
        BCD0 <= 0;
        end
    end
    
    
     always @(posedge up) begin
          if (BCD0 == 4'b1001) begin
            BCD0 <= 0;
            if (BCD1 == 4'b1001)
              BCD1 <= 0;
            else
              BCD1 <= BCD1 + 1;
          end
          else
            BCD0 <= BCD0 + 1;
        end
    
    
    always @(posedge down) begin
          if (BCD0 == 4'b0000) begin
            BCD0 <= 4'b1001;
            if (BCD1 == 4'b1001)
              BCD1 <= 4'b1001;
            else
              BCD1 <= BCD1 - 1;
          end
          else
            BCD0 <= BCD0 - 1;
        end
    
     assign BCD1_1 = BCD1;
     assign BCD0_0 = BCD0;
    
    endmodule