Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

FIFO Works fine on EDAPlayground but not Quartus

All,

The following code works fine and as expected on EDAPlayground, but Quartus has an issue with it.

I get the ERROR 10028 Can't resolve multiple constant drivers for nets w_addr and r_addr.

I am treating w_addr and r_addr as a temporary variable that can have a value 0 to 31, (5-bits)

Any ideas?

Thanks,

Keith

//////////////////////////////////////////////////////////////////////
//================================================================
// FIFO test in an array specfic for HiDS
// set up for Dual clocks
//      one to Write
//      one to Read
// also will need to have 2 data busses
//      Data IN
//      Data OUT
// Extras
//      nReset -- CLR on LO
//      Empty -- HI indicates empty
module DFIFO_array(D_Out, Empty, D_In, wrclk, rdclk, nrst);
  
  output  D_Out;
//output  D_Out;
  output Empty;
  reg  D_Out;
//reg  D_Out;
      
  input  D_In;
//input  D_In;
  
  input wrclk;
  input rdclk;
  input nrst;
  
  // 
  // DFIFO for 64 Channel SAM 41 x 32
  // EFIFO for 64 Channel SAM 10 x 64
  parameter WIDE = 41;
  parameter DEEP = 32;
  
  // this should give us a FIFO of 41 bits Wide by 32 words deep
  // 9-bit counter in MSB bits 32:41
  // 32-bit channel representation in 0:31 
  //
  // 
  reg  addr;
//reg  addr;
  reg  w_addr;
  reg  r_addr;
  
  always @ (posedge wrclk)
    begin
      addr <= D_In;
      w_addr <= w_addr + 1;
    end
  
  always @ (posedge rdclk)
    begin
      r_addr <= r_addr + 1;
      D_Out <= addr;
    end
  
  always @ (nrst)
    begin
      if (!nrst)
        begin
          w_addr <= 0;
          r_addr <= 0;
        end
    end
  
  assign Empty = (w_addr == r_addr);
  
endmodule
/////////////////////////////////////////////////////////////

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    All,

    The following code works fine and as expected on EDAPlayground, but Quartus has an issue with it.

    I get the ERROR 10028 Can't resolve multiple constant drivers for nets w_addr and r_addr.

    I am treating w_addr and r_addr as a temporary variable that can have a value 0 to 31, (5-bits)

    Any ideas?

    Thanks,

    Keith

    //////////////////////////////////////////////////////////////////////
    //================================================================
    // FIFO test in an array specfic for HiDS
    // set up for Dual clocks
    //      one to Write
    //      one to Read
    // also will need to have 2 data busses
    //      Data IN
    //      Data OUT
    // Extras
    //      nReset -- CLR on LO
    //      Empty -- HI indicates empty
    module DFIFO_array(D_Out, Empty, D_In, wrclk, rdclk, nrst);
      
      output  D_Out;
    //output  D_Out;
      output Empty;
      reg  D_Out;
    //reg  D_Out;
          
      input  D_In;
    //input  D_In;
      
      input wrclk;
      input rdclk;
      input nrst;
      
      // 
      // DFIFO for 64 Channel SAM 41 x 32
      // EFIFO for 64 Channel SAM 10 x 64
      parameter WIDE = 41;
      parameter DEEP = 32;
      
      // this should give us a FIFO of 41 bits Wide by 32 words deep
      // 9-bit counter in MSB bits 32:41
      // 32-bit channel representation in 0:31 
      //
      // 
      reg  addr;
    //reg  addr;
      reg  w_addr;
      reg  r_addr;
      
      always @ (posedge wrclk)
        begin
          addr <= D_In;
          w_addr <= w_addr + 1;
        end
      
      always @ (posedge rdclk)
        begin
          r_addr <= r_addr + 1;
          D_Out <= addr;
        end
      
      always @ (nrst)
        begin
          if (!nrst)
            begin
              w_addr <= 0;
              r_addr <= 0;
            end
        end
      
      assign Empty = (w_addr == r_addr);
      
    endmodule
    /////////////////////////////////////////////////////////////

    --- Quote End ---

    you need to insert the statements:

    w_addr <= 0;

    r_addr <= 0;

    so as to reset them in same top two processes.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    you need to insert the statements:

    w_addr <= 0;

    r_addr <= 0;

    so as to reset them in same top two processes.

    --- Quote End ---

    I guess I don't understand. If I reset them in each posedge process, then they will always be zero, and the array will not increment. I do set them to zero in my nrst section.

    Keith
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I guess I don't understand. If I reset them in each posedge process, then they will always be zero, and the array will not increment. I do set them to zero in my nrst section.

    Keith

    --- Quote End ---

    Inside each process the assignments are treated as sequential. But each process runs parallel to any other process.

    So by having separate processes on your same signal you are driving it twice in parallel. This is mutiple driver case and HDL standard is against it and I assume tools should respect it or not.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This is incorrect semantics for implementing a synchronously clocked register with an asynchronous reset:

    
      always @ (posedge rdclk)
        begin
          r_addr <= r_addr + 1;
          D_Out <= addr;
        end
      
      always @ (nrst)
        begin
          if (!nrst)
            begin
              r_addr <= 0;
            end
        end
    

    You need to rewrite the each register as a single always block:

    
      always @ (posedge rdclk or negedge nrst)
        begin
          if (!nrst)
               begin
               r_addr <= 0;
               end
          else
               begin
               r_addr <= r_addr + 1;
               D_Out <= addr;
               end
        end