Reply by rtstofer November 29, 20072007-11-29
--- In f..., "Eric Smith" wrote:
>
> > I guess I don't know how to do a vector assignment based on a logic
> > operation like:
> >
> > some_vector <= (some_other_vector AND a_std_signal ) OR
> > (another_vector AND some_other_std_signal);
>
> The logical operators are defined on std_logic_vector. The problem is
> that they aren't defined between a std_logic_vector and a std_logic.
> The easiest way to do this "inline" is to use an aggregate to expand
> the std_logic signal into a vector:
>
> some_vector <> (some_other_vector and (some_other_vector'range =>
a_std_signal)) or
> (another_vector and (another_vector'range =>
some_other_std_signal));
>
> That's cumbersome to type, so a better approach may be to write your
> own function to overload "and":
>
> function "and" (a: std_logic_vector;
> b: std_logic) return std_logic_vector is
> begin
> return a and (a'range => b);
> end;
>
> You can define that in your architecture (before the "begin", with your
> types, signals, etc.), or you can put it in a separate package and "use"
> it from multiple source files. Either way, you can then write:
>
> some_vector <= (some_other_vector and a_std_signal) or
> (another_vector and some_other_std_signal);
>
> Of course, you don't have to overload the "and" operator. You could
> define a function with a normal name such as andvs, and use that:
>
> some_vector <= andvs (some_other_vector, a_std_signal) or
> andvs (another_vector, some_other_std_signal);
>
> I prefer the overloading as I think the result is more readable, but
> some people don't seem to like overloading.
>
> Eric
>
I knew I would learn a lot when I posted this question. Yours is an
interesting solution!

I'll synthesize it tomorrow and see what it looks like...

Thanks
Richard

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by Brian Davis November 29, 20072007-11-29
--- In f..., "rtstofer" wrote:
>
> Consider something like:
>
> result <= a when sig1 = '1' else
> b when sig2 = '1' else
> c when sig3 = '1' else
> '0';
>
> The XST synthesis tool infers a priority encoder.
>
Is there a way to code this Verilog construct
> in VHDL that doesn't result in a priority encoder?
>

I usually use the with..select concurrent assignment
for something like that.


constant T_MOV : std_logic_vector( OP_MSB downto 0) := B"00";
constant T_AND : std_logic_vector( OP_MSB downto 0) := B"01";
constant T_OR : std_logic_vector( OP_MSB downto 0) := B"10";
constant T_XOR : std_logic_vector( OP_MSB downto 0) := B"11";



with logic_op select
logic_dat < ain AND logic_bin when T_AND,
ain OR logic_bin when T_OR,
ain XOR logic_bin when T_XOR,
logic_bin when T_MOV,

(others => 'X') when others;
If you need to paste together signals for a case/select
statement, define a subtype first like this:

subtype slv_4b is std_logic_vector(3 downto 0);
...
with slv_4b'( mem_size & mem_ea_dat(1 downto 0) ) select
Also of note, XST will support don't cares ('?') in
case/select choices, but I don't believe all synthesis
tools will accept this.

Brian

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by Eric Smith November 29, 20072007-11-29
> I wonder if it is worth
> messing around with tri-state to eliminate the 'or'?

No. By using tri-state, you're just forcing the synthesizer to
decide what to do, since the FPGA doesn't actually have tristate
busses internally. You're better off telling it explicitly what
you want.

Eric

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by Eric Smith November 29, 20072007-11-29
> Is there a way to code this Verilog construct in VHDL that doesn't
> result in a priority encoder? I would much prefer a MUX but I don't
> have a vector to use to select inputs.

Sure, just use "or" like you did in the Verilog ("|") instead of a
the "when" constructs.

Eric

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by Eric Smith November 28, 20072007-11-28
> I guess I don't know how to do a vector assignment based on a logic
> operation like:
>
> some_vector <= (some_other_vector AND a_std_signal ) OR
> (another_vector AND some_other_std_signal);

The logical operators are defined on std_logic_vector. The problem is
that they aren't defined between a std_logic_vector and a std_logic.
The easiest way to do this "inline" is to use an aggregate to expand
the std_logic signal into a vector:

some_vector < (some_other_vector and (some_other_vector'range => a_std_signal)) or
(another_vector and (another_vector'range => some_other_std_signal));

That's cumbersome to type, so a better approach may be to write your
own function to overload "and":

function "and" (a: std_logic_vector;
b: std_logic) return std_logic_vector is
begin
return a and (a'range => b);
end;

You can define that in your architecture (before the "begin", with your
types, signals, etc.), or you can put it in a separate package and "use"
it from multiple source files. Either way, you can then write:

some_vector <= (some_other_vector and a_std_signal) or
(another_vector and some_other_std_signal);

Of course, you don't have to overload the "and" operator. You could
define a function with a normal name such as andvs, and use that:

some_vector <= andvs (some_other_vector, a_std_signal) or
andvs (another_vector, some_other_std_signal);

I prefer the overloading as I think the result is more readable, but
some people don't seem to like overloading.

Eric

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by rtstofer November 28, 20072007-11-28
--- In f..., "Eric Smith" wrote:
>
> > I should have mentioned that in many cases, the code is dealing with
> > vectors rather than individual signals.
>
> And that would be a problem because... ?
>

I guess I don't know how to do a vector assignment based on a logic
operation like:

some_vector <= (some_other_vector AND a_std_signal ) OR
(another_vector AND some_other_std_signal);

in an attempt to get rid of the WHEN - ELSE construct.

It would certainly work when everything is a std_signal.

Richard

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by Tommy Thorn November 28, 20072007-11-28
> Another approach might be to break up the ALU into
> separate units:
> adder, shifter, bit operations, etc. Then MUX the
> results. I have
> seen some RISC designs that use that approach.

Actually, that *is* the classic approach, but
sometimes you can do better by merging operations or
being very clever with the implementation. See fx. "A
High Performance 32-bit ALU for Programmable Logic" in
FPGA'04. In my experience, those tricks doesn't really
help on "modern" FPGAs though, so as long as you keep
the muxes under control you'll be fine.

Quartus II will give you a ton of information about
the muxes it found and how many resources they take.
ISE might have something similar.

Tommy

____________________________________________________________________________________
Never miss a thing. Make Yahoo your home page.
http://www.yahoo.com/r/hs
To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by Eric Smith November 28, 20072007-11-28
> I should have mentioned that in many cases, the code is dealing with
> vectors rather than individual signals.

And that would be a problem because... ?

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by rtstofer November 28, 20072007-11-28
--- In f..., "Eric Smith" wrote:
>
> > Is there a way to code this Verilog construct in VHDL that doesn't
> > result in a priority encoder? I would much prefer a MUX but I don't
> > have a vector to use to select inputs.
>
> Sure, just use "or" like you did in the Verilog ("|") instead of a
> the "when" constructs.
>
> Eric
>

I should have mentioned that in many cases, the code is dealing with
vectors rather than individual signals.

I recoded the ALU in cleaned-up Verilog and compared it to VHDL. In
the end, there is one level difference. It's either 28 levels
(Verilog) or 29 levels (VHDL) for the PDP-11/40 ALU and the delays
(ignoring IBUF and OBUF) are on the order of 40 nS for a Spartan IIE
speed grade 6.

Given that the prototype only runs at 20 MHz, I still have a little
margin.

Another approach might be to break up the ALU into separate units:
adder, shifter, bit operations, etc. Then MUX the results. I have
seen some RISC designs that use that approach.

Richard

To post a message, send it to: f...
To unsubscribe, send a blank message to: f...
Reply by Tommy Thorn November 28, 20072007-11-28
> You could do worse than check out
> http://www.cs.tut.fi/soc/Metzgen04.pdf
> Even though it's an Altera perspective, the general
> principles holds true for Xilinx as well.

This one is even more explicitly on the mux issue:
Multiplexer Restructuring for FPGA Implementation Cost
Reduction
(http://www.soccentral.com/goto.asp?EntryID999)

Tommy

____________________________________________________________________________________
Get easy, one-click access to your favorites.
Make Yahoo! your homepage.
http://www.yahoo.com/r/hs
To post a message, send it to: f...
To unsubscribe, send a blank message to: f...