I have an ASIC design using internal tri-state multi-sources buses
like below:
assign tbus = a_en ? a : Hiz;
assign tbus = b_en ? b : Hiz;
When implementing to FPGA, I found I can't strobe the right data from
the bus. After analyze the code, I think it's because the strobe
signal comes later than the enable signals for each source. For a real
tri-state bus, the value can still float on the bus so the ASIC can
work.
For the FPGA, I think I need convert the bus using latch to contain
the value when the enable signal has gone, so I designed the code like
below:
always @(*)
begin
if (a_en)
tbus <= a;
else if (b_en)
tbus <= b;
end
However the circuit doesn't work as I expected, I examined the
synthesis result, looks like my code is translated to a mux and a
latch like below:
assign temp = a_en ? a : b;
always @(*)
if (a_en | b_en)
tbus <= temp;
It seems Verilog doesn't accept an incomplete Mux, so b is set as
default.
On Nov 13, 9:19*am, jay <heavenf...@gmail.com> wrote:
> Hello,
>
> I have an ASIC design using internal tri-state multi-sources buses
> like below:
> assign tbus = a_en ? a : Hiz;
> assign tbus = b_en ? b : Hiz;
>
> When implementing to FPGA, I found I can't strobe the right data from
> the bus. After analyze the code, I think it's because the strobe
> signal comes later than the enable signals for each source. For a real
> tri-state bus, the value can still float on the bus so the ASIC can
> work.
>
> For the FPGA, I think I need convert the bus using latch to contain
> the value when the enable signal has gone, so I designed the code like
> below:
> always @(*)
> begin
> * if (a_en)
> * * tbus <= a;
> * else if (b_en)
> * * tbus <= b;
> end
>
> However the circuit doesn't work as I expected, I examined the
> synthesis result, looks like my code is translated to a mux and a
> latch like below:
> assign temp = a_en ? a : b;
> always @(*)
> * if (a_en | b_en)
> * * tbus <= temp;
>
> It seems Verilog doesn't accept an incomplete Mux, so b is set as
> default.
>
> Can anyone gives me some advise?
>
> Thanks
The problem is using a_en as both the mux select and the latch
gate doesn't give any hold time when latching the A input.
You may want to recode it using a S/R latch for the mux select
to meet the hold time after a_en. As you have started to
discover, FPGA's are not great at asynchronous sequential logic.
At least they do contain gated latches, and you should check the
synthesis results to be sure the latch is in use rather than
trying to use LUT's as latch gate elements. Which FPGA family
are you using?
On Nov 13, 6:19*am, jay <heavenf...@gmail.com> wrote:
> Hello,
>
> I have an ASIC design using internal tri-state multi-sources buses
> like below:
> assign tbus = a_en ? a : Hiz;
> assign tbus = b_en ? b : Hiz;
>
> When implementing to FPGA, I found I can't strobe the right data from
> the bus. After analyze the code, I think it's because the strobe
> signal comes later than the enable signals for each source. For a real
> tri-state bus, the value can still float on the bus so the ASIC can
> work.
>
> For the FPGA, I think I need convert the bus using latch to contain
> the value when the enable signal has gone, so I designed the code like
> below:
> always @(*)
> begin
> * if (a_en)
> * * tbus <= a;
> * else if (b_en)
> * * tbus <= b;
> end
>
> However the circuit doesn't work as I expected, I examined the
> synthesis result, looks like my code is translated to a mux and a
> latch like below:
> assign temp = a_en ? a : b;
> always @(*)
> * if (a_en | b_en)
> * * tbus <= temp;
>
> It seems Verilog doesn't accept an incomplete Mux, so b is set as
> default.
>
> Can anyone gives me some advise?
>
> Thanks
What is your setup/hold of the data and the enables? You may need to
code this as
latches followed by a mux and not a mux followed by a latch.
always @(*)
if (a_en | (a & a_hold)
a_hold = a;
always @(*)
if (b_en | (b & b_hold)
b_hold = b;
assign t_bus = a_en ? a_hold : b_hold;
Make sure that the synthesizer infers the latches properly, you may
need to use the simpler:
always @(&)
if (b_en)
b_hold = b;
Adding the extra term in the "if" solves a race condition when the
latch enable is removed and you're
making the latch out of discrete gates. This is probably not needed
since the latch inferred by synthesis
should alreay take care of this.
On Nov 13, 10:45*pm, Gabor <ga...@alacron.com> wrote:
> On Nov 13, 9:19*am, jay <heavenf...@gmail.com> wrote:
>
>
>
> > Hello,
>
> > I have an ASIC design using internal tri-state multi-sources buses
> > like below:
> > assign tbus = a_en ? a : Hiz;
> > assign tbus = b_en ? b : Hiz;
>
> > When implementing to FPGA, I found I can't strobe the right data from
> > the bus. After analyze the code, I think it's because the strobe
> > signal comes later than the enable signals for each source. For a real
> > tri-state bus, the value can still float on the bus so the ASIC can
> > work.
>
> > For the FPGA, I think I need convert the bus using latch to contain
> > the value when the enable signal has gone, so I designed the code like
> > below:
> > always @(*)
> > begin
> > * if (a_en)
> > * * tbus <= a;
> > * else if (b_en)
> > * * tbus <= b;
> > end
>
> > However the circuit doesn't work as I expected, I examined the
> > synthesis result, looks like my code is translated to a mux and a
> > latch like below:
> > assign temp = a_en ? a : b;
> > always @(*)
> > * if (a_en | b_en)
> > * * tbus <= temp;
>
> > It seems Verilog doesn't accept an incomplete Mux, so b is set as
> > default.
>
> > Can anyone gives me some advise?
>
> > Thanks
>
> The problem is using a_en as both the mux select and the latch
> gate doesn't give any hold time when latching the A input.
> You may want to recode it using a S/R latch for the mux select
> to meet the hold time after a_en. *As you have started to
> discover, FPGA's are not great at asynchronous sequential logic.
> At least they do contain gated latches, and you should check the
> synthesis results to be sure the latch is in use rather than
> trying to use LUT's as latch gate elements. *Which FPGA family
> are you using?
>
> Regards,
> Gabor
Good idea, S/R latch should work if I only had two enables, but
there's more in my design. I think I need a state machine.
I'm using spartan-3a, it has d-latch resources, probably no sr-latch.
On Nov 13, 10:58*pm, johnp <jprovide...@yahoo.com> wrote:
> On Nov 13, 6:19*am, jay <heavenf...@gmail.com> wrote:
>
>
>
> > Hello,
>
> > I have an ASIC design using internal tri-state multi-sources buses
> > like below:
> > assign tbus = a_en ? a : Hiz;
> > assign tbus = b_en ? b : Hiz;
>
> > When implementing to FPGA, I found I can't strobe the right data from
> > the bus. After analyze the code, I think it's because the strobe
> > signal comes later than the enable signals for each source. For a real
> > tri-state bus, the value can still float on the bus so the ASIC can
> > work.
>
> > For the FPGA, I think I need convert the bus using latch to contain
> > the value when the enable signal has gone, so I designed the code like
> > below:
> > always @(*)
> > begin
> > * if (a_en)
> > * * tbus <= a;
> > * else if (b_en)
> > * * tbus <= b;
> > end
>
> > However the circuit doesn't work as I expected, I examined the
> > synthesis result, looks like my code is translated to a mux and a
> > latch like below:
> > assign temp = a_en ? a : b;
> > always @(*)
> > * if (a_en | b_en)
> > * * tbus <= temp;
>
> > It seems Verilog doesn't accept an incomplete Mux, so b is set as
> > default.
>
> > Can anyone gives me some advise?
>
> > Thanks
>
> What is your setup/hold of the data and the enables? *You may need to
> code this as
> latches followed by a mux and not a mux followed by a latch.
>
> always @(*)
> * if (a_en | (a & a_hold)
> * * *a_hold = a;
>
> always @(*)
> * if (b_en | (b & b_hold)
> * * b_hold = b;
>
> assign t_bus = a_en ? a_hold : b_hold;
>
> Make sure that the synthesizer infers the latches properly, you may
> need to use the simpler:
> * always @(&)
> * * *if (b_en)
> * * * * *b_hold = b;
>
> Adding the extra term in the "if" solves a race condition when the
> latch enable is removed and you're
> making the latch out of discrete gates. *This is probably not needed
> since the latch inferred by synthesis
> should alreay take care of this.
>
> I hope this helps!
>
> John Providenza
I haven't seen "always @(&)" before, a new syntax?
On Nov 13, 11:00*am, jay <heavenf...@gmail.com> wrote:
> On Nov 13, 10:45*pm, Gabor <ga...@alacron.com> wrote:
>
>
>
> > On Nov 13, 9:19*am, jay <heavenf...@gmail.com> wrote:
>
> > > Hello,
>
> > > I have an ASIC design using internal tri-state multi-sources buses
> > > like below:
> > > assign tbus = a_en ? a : Hiz;
> > > assign tbus = b_en ? b : Hiz;
>
> > > When implementing to FPGA, I found I can't strobe the right data from
> > > the bus. After analyze the code, I think it's because the strobe
> > > signal comes later than the enable signals for each source. For a real
> > > tri-state bus, the value can still float on the bus so the ASIC can
> > > work.
>
> > > For the FPGA, I think I need convert the bus using latch to contain
> > > the value when the enable signal has gone, so I designed the code like
> > > below:
> > > always @(*)
> > > begin
> > > * if (a_en)
> > > * * tbus <= a;
> > > * else if (b_en)
> > > * * tbus <= b;
> > > end
>
> > > However the circuit doesn't work as I expected, I examined the
> > > synthesis result, looks like my code is translated to a mux and a
> > > latch like below:
> > > assign temp = a_en ? a : b;
> > > always @(*)
> > > * if (a_en | b_en)
> > > * * tbus <= temp;
>
> > > It seems Verilog doesn't accept an incomplete Mux, so b is set as
> > > default.
>
> > > Can anyone gives me some advise?
>
> > > Thanks
>
> > The problem is using a_en as both the mux select and the latch
> > gate doesn't give any hold time when latching the A input.
> > You may want to recode it using a S/R latch for the mux select
> > to meet the hold time after a_en. *As you have started to
> > discover, FPGA's are not great at asynchronous sequential logic.
> > At least they do contain gated latches, and you should check the
> > synthesis results to be sure the latch is in use rather than
> > trying to use LUT's as latch gate elements. *Which FPGA family
> > are you using?
>
> > Regards,
> > Gabor
>
> Good idea, S/R latch should work if I only had two enables, but
> there's more in my design. I think I need a state machine.
>
> I'm using spartan-3a, it has d-latch resources, probably no sr-latch.
Actually there are flip-flops with async preset and clear. If you tie
off the clock and D it becomes an SR latch.
On Nov 13, 8:34*am, jay <heavenf...@gmail.com> wrote:
> On Nov 13, 10:58*pm, johnp <jprovide...@yahoo.com> wrote:
>
>
>
> > On Nov 13, 6:19*am, jay <heavenf...@gmail.com> wrote:
>
> > > Hello,
>
> > > I have an ASIC design using internal tri-state multi-sources buses
> > > like below:
> > > assign tbus = a_en ? a : Hiz;
> > > assign tbus = b_en ? b : Hiz;
>
> > > When implementing to FPGA, I found I can't strobe the right data from
> > > the bus. After analyze the code, I think it's because the strobe
> > > signal comes later than the enable signals for each source. For a real
> > > tri-state bus, the value can still float on the bus so the ASIC can
> > > work.
>
> > > For the FPGA, I think I need convert the bus using latch to contain
> > > the value when the enable signal has gone, so I designed the code like
> > > below:
> > > always @(*)
> > > begin
> > > * if (a_en)
> > > * * tbus <= a;
> > > * else if (b_en)
> > > * * tbus <= b;
> > > end
>
> > > However the circuit doesn't work as I expected, I examined the
> > > synthesis result, looks like my code is translated to a mux and a
> > > latch like below:
> > > assign temp = a_en ? a : b;
> > > always @(*)
> > > * if (a_en | b_en)
> > > * * tbus <= temp;
>
> > > It seems Verilog doesn't accept an incomplete Mux, so b is set as
> > > default.
>
> > > Can anyone gives me some advise?
>
> > > Thanks
>
> > What is your setup/hold of the data and the enables? *You may need to
> > code this as
> > latches followed by a mux and not a mux followed by a latch.
>
> > always @(*)
> > * if (a_en | (a & a_hold)
> > * * *a_hold = a;
>
> > always @(*)
> > * if (b_en | (b & b_hold)
> > * * b_hold = b;
>
> > assign t_bus = a_en ? a_hold : b_hold;
>
> > Make sure that the synthesizer infers the latches properly, you may
> > need to use the simpler:
> > * always @(&)
> > * * *if (b_en)
> > * * * * *b_hold = b;
>
> > Adding the extra term in the "if" solves a race condition when the
> > latch enable is removed and you're
> > making the latch out of discrete gates. *This is probably not needed
> > since the latch inferred by synthesis
> > should alreay take care of this.
>
> > I hope this helps!
>
> > John Providenza
>
> I haven't seen "always @(&)" before, a new syntax?
When I had to implement tri-state buffers onto FPGAs I've always
used FPGA-specific gates, e.g., "tri" buffers on Altera. I could
suggest you to look at the logic family you are using, probably
they have a solution for your issue.
You exactly have pointed out the problem with this alternative
description. Nevertheless it does not solve the problem.
To be more precise: Let's say a_en==1'b1 then signal a is selected and
the latch is open. Now with the falling edge of a_en the mux may change
it's output value AND the latch becomes inactive. No one can say witch
one is faster. A hold time violation is the result in simulation and
unpredictable results are the result in hardware.
Don't use muxed latches! Don't do it in ASICS or in FPGAs.
Find a new signal that drives the mux-selector!