Forum Discussion
Altera_Forum
Honored Contributor
8 years agoFIFO 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
Honored 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
--- Quote End --- you need to insert the statements: w_addr <= 0; r_addr <= 0; so as to reset them in same top two processes.////////////////////////////////////////////////////////////////////// //================================================================ // 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 ///////////////////////////////////////////////////////////// - Altera_Forum
Honored 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
Honored 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
Honored Contributor
You need reset outside (before) clock edge
- Altera_Forum
Honored Contributor
This is incorrect semantics for implementing a synchronously clocked register with an asynchronous reset:
You need to rewrite the each register as a single always block:always @ (posedge rdclk) begin r_addr <= r_addr + 1; D_Out <= addr; end always @ (nrst) begin if (!nrst) begin r_addr <= 0; end endalways @ (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