On Apr 14, 4:55 pm, "Alvin Andries"
<Alvin_Andries.no_s...@no.spam.versateladsl.be> wrote:
> "NRClark" <nicholas.cl...@gmail.com> wrote in message
>
> news:5b377f74-9395-46de-b771-dccba3d994d1@k1g2000prb.googlegroups.com...
>
>
>
> > Hi everybody,
>
> > I'm working on a hobbyist board I'm designing to do some audio DSP.
> > I'm a little new to Verilog,
> > although not to programming in general. So far the FPGA design work
> > has been going smoothly
> > enough, but I'm having some trouble with synthesizing the code I wrote
> > for my DAC. I tried to avoid
> > all of the 'common' mistakes and design for synthesizability, but
> > there's some I must have missed.
>
> > My design simulates just fine, but when I go to synthesize it I get
> > these weird "Multi-source" errors:
>
> > ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> > <shift_counter<4>>
> > ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> > <shift_counter<2>>
> > ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> > <shift_counter<1>>
> > ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> > <Msub__COND_2_Madd>
> > ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> > <Mcount_shift_counter>.
>
> > I can't find the bug in my design, which means it must be some bug in
> > my own understanding. :)
>
> > Any words of insight? My Verilog code follows.
>
> > Thanks,
> > Nick
>
> > //------------------------------------
> > code----------------------------------------
> > module dac_cs4345(CLK, RST_N, SCLK,
> > LRCLK, L_DATA, R_DATA,
> > DATAOUT);
>
> > // In this design, CLK = 49.152MHz, MCLK = 24.576MHz,
> > // SCLK = 6.144MHz, LRCLK = 96KHz. They are all in-phase
> > // each other, with the various clocks being generated from
> > // a 49.152MHz crystal and another Veriog module containing
> > // counters.
>
> > // Module port declarations
>
> > input CLK, RST_N;
> > input SCLK, LRCLK;
> > input [23:0] L_DATA, R_DATA;
>
> > output reg DATAOUT;
>
> > // Internal declarations
>
> > reg r1, r2;
> > wire SCLK_DELAYED;
>
> > // Counter used as an index to access data serially.
> > reg [4:0] shift_counter;
>
> > // L_Data and R_Data are both registered to protect against
> > // spurious transitions during conversion.
> > reg [23:0] L_DATA_STORAGE;
> > reg [23:0] R_DATA_STORAGE;
>
> > // Begin Program
>
> > // Since our data is set up on the LRCLK edge, we have to allow
> > // some delay before accessing it. Since SCLK is the clock used
> > // pull data, a slightly delayed SCLK will be generated and used.
> > // SCLK_DELAYED arrives one CLK period after SCLK.
>
> > always @(posedge CLK) begin
> > r2 <= r1;
> > r1 <= SCLK;
> > end
> > assign SCLK_DELAYED = r2;
>
> > // Both the L and R data are assumed to arrive at this module
> > // at the same time, and to be available at the rising
> > // edge of the provided LRCLK. Since LRCLK is the output
> > // waveform used for synching data, this is a valid assumption.
> > // L_data and R_data _must_ be set up some time before the
> > // positive edge of LRCLK.
>
> > always @(posedge LRCLK) begin
> > L_DATA_STORAGE <= L_DATA;
> > R_DATA_STORAGE <= R_DATA;
> > shift_counter <= 31; // Reset count-down counter
> > end
>
> > always @(negedge LRCLK)
> > shift_counter <= 31; // Reset count-down counter
>
> > // Output data is assigned here. DATAOUT is assigned the value of
> > // 0 if our counter has gone past the data's LSB. The DAC's
> > // left-channel data is supplied when LRCLK is high, and its
> > // right-channel data is spplied when LRCLK is low.
>
> > always @(posedge SCLK_DELAYED) begin
> > if(shift_counter < 8)
> > DATAOUT = 0;
> > else if(LRCLK == 1)
> > DATAOUT = L_DATA_STORAGE[shift_counter-8];
> > else
> > DATAOUT = R_DATA_STORAGE[shift_counter-8];
> > end
>
> > // The timing of this is such that shift_counter counts down
> > // from 32 to 0 twice in each LRCLK - once per 'side'. This is
> > // decremented after the output has already been assigned a value.
> > // shift_counter could also be decremented on the falling edge of
> > // SCLK_DELAYED without changing the result.
>
> > always @(negedge SCLK) begin
> > shift_counter <= shift_counter-1;
> > end
>
> > endmodule
>
> You adjust shift_counter in multiple processes (always @), which won't do.
> You should only have 1 clocked process modifying shift_counter.
> With all clocks being synchronously divided versions of CLK = 49.152MHz, you
> should substitute the other clocks by "enable"/edge detect signals clocked
> on CLK. The low frequency clocks can still be made available/imported from
> the external world.
>
> Regards,
> Alvin.
Also in XST every clocked register needs to fit a flip-flop template.
You can't have posedge and negedge of the same clock for example, even
if you place the code in the same always block. In Xilinx parts dual
clocked flip-flops (DDR flops) only exist in the I/O blocks and must
be instantiated, not inferred. The standard template for an
asynchronous set/reset flip-flop looks like:
always @ (negedge SCLK or posedge LRCLK)
if (LRCLK) // active high async reset on LRCLK
begin
shift_counter <= 31; // Reset count-down counter
end
else // negedge SCLK
begin
shift_counter <= shift_counter-1;
end
Regards,
Gabor
Reply by Alvin Andries●April 14, 20082008-04-14
"NRClark" <nicholas.clark@gmail.com> wrote in message
news:5b377f74-9395-46de-b771-dccba3d994d1@k1g2000prb.googlegroups.com...
> Hi everybody,
>
> I'm working on a hobbyist board I'm designing to do some audio DSP.
> I'm a little new to Verilog,
> although not to programming in general. So far the FPGA design work
> has been going smoothly
> enough, but I'm having some trouble with synthesizing the code I wrote
> for my DAC. I tried to avoid
> all of the 'common' mistakes and design for synthesizability, but
> there's some I must have missed.
>
> My design simulates just fine, but when I go to synthesize it I get
> these weird "Multi-source" errors:
>
> ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> <shift_counter<4>>
> ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> <shift_counter<2>>
> ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> <shift_counter<1>>
> ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> <Msub__COND_2_Madd>
> ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
> <Mcount_shift_counter>.
>
> I can't find the bug in my design, which means it must be some bug in
> my own understanding. :)
>
> Any words of insight? My Verilog code follows.
>
> Thanks,
> Nick
>
> //------------------------------------
> code----------------------------------------
> module dac_cs4345(CLK, RST_N, SCLK,
> LRCLK, L_DATA, R_DATA,
> DATAOUT);
>
> // In this design, CLK = 49.152MHz, MCLK = 24.576MHz,
> // SCLK = 6.144MHz, LRCLK = 96KHz. They are all in-phase
> // each other, with the various clocks being generated from
> // a 49.152MHz crystal and another Veriog module containing
> // counters.
>
> // Module port declarations
>
> input CLK, RST_N;
> input SCLK, LRCLK;
> input [23:0] L_DATA, R_DATA;
>
> output reg DATAOUT;
>
> // Internal declarations
>
> reg r1, r2;
> wire SCLK_DELAYED;
>
> // Counter used as an index to access data serially.
> reg [4:0] shift_counter;
>
> // L_Data and R_Data are both registered to protect against
> // spurious transitions during conversion.
> reg [23:0] L_DATA_STORAGE;
> reg [23:0] R_DATA_STORAGE;
>
> // Begin Program
>
> // Since our data is set up on the LRCLK edge, we have to allow
> // some delay before accessing it. Since SCLK is the clock used
> // pull data, a slightly delayed SCLK will be generated and used.
> // SCLK_DELAYED arrives one CLK period after SCLK.
>
> always @(posedge CLK) begin
> r2 <= r1;
> r1 <= SCLK;
> end
> assign SCLK_DELAYED = r2;
>
> // Both the L and R data are assumed to arrive at this module
> // at the same time, and to be available at the rising
> // edge of the provided LRCLK. Since LRCLK is the output
> // waveform used for synching data, this is a valid assumption.
> // L_data and R_data _must_ be set up some time before the
> // positive edge of LRCLK.
>
> always @(posedge LRCLK) begin
> L_DATA_STORAGE <= L_DATA;
> R_DATA_STORAGE <= R_DATA;
> shift_counter <= 31; // Reset count-down counter
> end
>
> always @(negedge LRCLK)
> shift_counter <= 31; // Reset count-down counter
>
> // Output data is assigned here. DATAOUT is assigned the value of
> // 0 if our counter has gone past the data's LSB. The DAC's
> // left-channel data is supplied when LRCLK is high, and its
> // right-channel data is spplied when LRCLK is low.
>
> always @(posedge SCLK_DELAYED) begin
> if(shift_counter < 8)
> DATAOUT = 0;
> else if(LRCLK == 1)
> DATAOUT = L_DATA_STORAGE[shift_counter-8];
> else
> DATAOUT = R_DATA_STORAGE[shift_counter-8];
> end
>
> // The timing of this is such that shift_counter counts down
> // from 32 to 0 twice in each LRCLK - once per 'side'. This is
> // decremented after the output has already been assigned a value.
> // shift_counter could also be decremented on the falling edge of
> // SCLK_DELAYED without changing the result.
>
> always @(negedge SCLK) begin
> shift_counter <= shift_counter-1;
> end
>
> endmodule
You adjust shift_counter in multiple processes (always @), which won't do.
You should only have 1 clocked process modifying shift_counter.
With all clocks being synchronously divided versions of CLK = 49.152MHz, you
should substitute the other clocks by "enable"/edge detect signals clocked
on CLK. The low frequency clocks can still be made available/imported from
the external world.
Regards,
Alvin.
Reply by NRClark●April 14, 20082008-04-14
Hi everybody,
I'm working on a hobbyist board I'm designing to do some audio DSP.
I'm a little new to Verilog,
although not to programming in general. So far the FPGA design work
has been going smoothly
enough, but I'm having some trouble with synthesizing the code I wrote
for my DAC. I tried to avoid
all of the 'common' mistakes and design for synthesizability, but
there's some I must have missed.
My design simulates just fine, but when I go to synthesize it I get
these weird "Multi-source" errors:
ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
<shift_counter<4>>
ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
<shift_counter<2>>
ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
<shift_counter<1>>
ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
<Msub__COND_2_Madd>
ERROR:Xst:528 - Multi-source in Unit <dac_cs4345> on signal
<Mcount_shift_counter>.
I can't find the bug in my design, which means it must be some bug in
my own understanding. :)
Any words of insight? My Verilog code follows.
Thanks,
Nick
//------------------------------------
code----------------------------------------
module dac_cs4345(CLK, RST_N, SCLK,
LRCLK, L_DATA, R_DATA,
DATAOUT);
// In this design, CLK = 49.152MHz, MCLK = 24.576MHz,
// SCLK = 6.144MHz, LRCLK = 96KHz. They are all in-phase
// each other, with the various clocks being generated from
// a 49.152MHz crystal and another Veriog module containing
// counters.
// Module port declarations
input CLK, RST_N;
input SCLK, LRCLK;
input [23:0] L_DATA, R_DATA;
output reg DATAOUT;
// Internal declarations
reg r1, r2;
wire SCLK_DELAYED;
// Counter used as an index to access data serially.
reg [4:0] shift_counter;
// L_Data and R_Data are both registered to protect against
// spurious transitions during conversion.
reg [23:0] L_DATA_STORAGE;
reg [23:0] R_DATA_STORAGE;
// Begin Program
// Since our data is set up on the LRCLK edge, we have to allow
// some delay before accessing it. Since SCLK is the clock used
// pull data, a slightly delayed SCLK will be generated and used.
// SCLK_DELAYED arrives one CLK period after SCLK.
always @(posedge CLK) begin
r2 <= r1;
r1 <= SCLK;
end
assign SCLK_DELAYED = r2;
// Both the L and R data are assumed to arrive at this module
// at the same time, and to be available at the rising
// edge of the provided LRCLK. Since LRCLK is the output
// waveform used for synching data, this is a valid assumption.
// L_data and R_data _must_ be set up some time before the
// positive edge of LRCLK.
always @(posedge LRCLK) begin
L_DATA_STORAGE <= L_DATA;
R_DATA_STORAGE <= R_DATA;
shift_counter <= 31; // Reset count-down counter
end
always @(negedge LRCLK)
shift_counter <= 31; // Reset count-down counter
// Output data is assigned here. DATAOUT is assigned the value of
// 0 if our counter has gone past the data's LSB. The DAC's
// left-channel data is supplied when LRCLK is high, and its
// right-channel data is spplied when LRCLK is low.
always @(posedge SCLK_DELAYED) begin
if(shift_counter < 8)
DATAOUT = 0;
else if(LRCLK == 1)
DATAOUT = L_DATA_STORAGE[shift_counter-8];
else
DATAOUT = R_DATA_STORAGE[shift_counter-8];
end
// The timing of this is such that shift_counter counts down
// from 32 to 0 twice in each LRCLK - once per 'side'. This is
// decremented after the output has already been assigned a value.
// shift_counter could also be decremented on the falling edge of
// SCLK_DELAYED without changing the result.
always @(negedge SCLK) begin
shift_counter <= shift_counter-1;
end
endmodule