Sign in

username:

password:



Not a member?

Search fpga-cpu



Search tips

Subscribe to fpga-cpu



fpga-cpu by Keywords

Altera | CISCifying | IDE | ISA | Java | JHDL | JTAG | LBU | MicroBlaze | PAR | PCI | RISC | SoC | Spartan | Transputers | Verilog | VHDL | Virtex | VLIW | WebPack | Xilinx | Xsoc | YARD-1A

Ads

Discussion Groups

Discussion Groups | FPGA-CPU | Strange syntax

This list is for discussion of the design and implementation of field-programmable gate array based processors and integrated systems. It is also for discussion and community support of the XSOC Project (see http://www.fpgacpu.org/xsoc).

Strange syntax - rtstofer - Dec 20 17:06:40 2007

In a project I didn't create there are expressions of the form:

if (atmp+btmp)(8) = '1'
then sr_c_ctrl <= SR_C_SET;
else sr_c_ctrl <= SR_C_CLR;
end if;

where atmp and btmp are std_logic_vector(8 downto 0) and are being
used to add 2 8 bit operands and allow access to bit 8 of the result
as the carry out.

This syntax is apparently acceptable for Lattice but Xilinx XST isn't
having any part of it.

Are there any simple ways to fix this other than building a new
arithmetic unit? There are 59 occurances of this syntax and I would
rather not rewrite a lot of code at this stage.

Thanks
Richard

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )


Re: Strange syntax - Kolja Sulimma - Dec 20 18:16:21 2007

1.
make sure you have only IEEE.NUMERIC_STD.ALL and none of the deprecated
STD_LOGIC_ARITH or STD_LOGIC_UNSIGNED stuff.

2.
declare atmp and btmp as unsigned(8 downto 0);

3.
if (atmp+btmp) > 255 then...

The synthesized hardware should be exactly the same.

Kolja Sulimma

2007/12/20, rtstofer :
>
> In a project I didn't create there are expressions of the form:
>
> if (atmp+btmp)(8) = '1'
> then sr_c_ctrl <= SR_C_SET;
> else sr_c_ctrl <= SR_C_CLR;
> end if;
>
> where atmp and btmp are std_logic_vector(8 downto 0) and are being
> used to add 2 8 bit operands and allow access to bit 8 of the result
> as the carry out.
>
> This syntax is apparently acceptable for Lattice but Xilinx XST isn't
> having any part of it.
>
> Are there any simple ways to fix this other than building a new
> arithmetic unit? There are 59 occurances of this syntax and I would
> rather not rewrite a lot of code at this stage.
>
> Thanks
> Richard
>
>
>

--
cronologic ohg Frankfurt am Main
HRA 42869 beim Amtsgericht Frankfurt
Telefon 069 38 09 78 254
[Non-text portions of this message have been removed]

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Strange syntax - Eric Smith - Dec 20 20:04:47 2007

Richard wrote:
> In a project I didn't create there are expressions of the form:
> if (atmp+btmp)(8) = '1'
[...]
> This syntax is apparently acceptable for Lattice but Xilinx XST isn't
> having any part of it.
[...]
> There are 59 occurances of this syntax and I would
> rather not rewrite a lot of code at this stage.

It's a matter of whether the used libraries define addition on the
std_logic_vector type. Apparently you've using a library that
does w/ Lattice but does not w/ Xilinx.

Although it's generally considered bad form because they aren't
actually standardized, you can probably solve this by using
std_logic_arith or std_logic_unsigned.

A somewhat better approach to fixing it without having to make many
changes to the source files would be to use IEEE.numeric_std, and
define your own function overloading the addition operator, e.g. the
following completely untested code:

library IEEE;
use IEEE.std_logic_1164.all;

package my_arith is
function "+" (a: std_logic_vector; b: std_logic_vector)
return std_logic_vector is
begin
return to_stdlogicvector (to_unsigned (a) + to_unsigned (b));
end "+";
end my_arith;
You don't have to use a package to do this; you can put the function
definition directly into the declaration part of the architecture
that needs it.

If you don't mind making a simple change to the 59 occurrences, I
think it would be better to give the function a normal name rather
than overloading the addition operator. Then your if statement
would become:
if unsigned_add (atmp, btmp) (8) = '1'

Eric

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Strange syntax - rtstofer - Dec 20 20:36:26 2007

> A somewhat better approach to fixing it without having to make many
> changes to the source files would be to use IEEE.numeric_std, and
> define your own function overloading the addition operator, e.g. the
> following completely untested code:
>
> library IEEE;
> use IEEE.std_logic_1164.all;
>
> package my_arith is
> function "+" (a: std_logic_vector; b: std_logic_vector)
> return std_logic_vector is
> begin
> return to_stdlogicvector (to_unsigned (a) + to_unsigned (b));
> end "+";
> end my_arith;
> You don't have to use a package to do this; you can put the function
> definition directly into the declaration part of the architecture
> that needs it.
>
> If you don't mind making a simple change to the 59 occurrences, I
> think it would be better to give the function a normal name rather
> than overloading the addition operator. Then your if statement
> would become:
> if unsigned_add (atmp, btmp) (8) = '1'
>
> Eric
>

I like the 'unsigned_add' approach. This particular ALU needs to
add, subtract, add with carry, subtract with borrow and, by the way,
do it for binary and BCD. That's why the code has so many occurances
of these statements; there are a lot of different cases.

I may be able to do the whole process in a procedure and clean up the
entire CPU.

Thanks
Richard

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Strange syntax - rtstofer - Dec 20 21:36:58 2007

--- In f...@yahoogroups.com, "Eric Smith" wrote:
>
> Richard wrote:
> > This particular ALU needs to
> > add, subtract, add with carry, subtract with borrow and, by the way,
> > do it for binary and BCD. That's why the code has so many occurances
> > of these statements; there are a lot of different cases.
> >
> > I may be able to do the whole process in a procedure and clean up the
> > entire CPU.
>
> Even with it in a procedure, I expect the synthesizer will try to
> create 59 adders for you. If you really want only one (or a small
> number) of adders, I think you're best off making your VHDL look
> a little more like structural code.
>
> A few years ago I designed a high-speed 56-bit binary/BCD
adder/subtracter
> using four-bit carry-select adders and carry lookahead. In the slow
> speed grade Spartan-3, the complete data path including three general
> registers and the multiplexers for the adder inputs runs at over 50 MHz.
>
> Best regards,
> Eric
>

No doubt you are right about eventually having to design a proper
adder. It's not a big effort because I already have most of it on
another project.

I just need to yank a lot of code that, at the moment, I would rather
leave essentially stock.

Richard

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Re: Strange syntax - Eric Smith - Dec 20 21:46:12 2007

Richard wrote:
> This particular ALU needs to
> add, subtract, add with carry, subtract with borrow and, by the way,
> do it for binary and BCD. That's why the code has so many occurances
> of these statements; there are a lot of different cases.
>
> I may be able to do the whole process in a procedure and clean up the
> entire CPU.

Even with it in a procedure, I expect the synthesizer will try to
create 59 adders for you. If you really want only one (or a small
number) of adders, I think you're best off making your VHDL look
a little more like structural code.

A few years ago I designed a high-speed 56-bit binary/BCD adder/subtracter
using four-bit carry-select adders and carry lookahead. In the slow
speed grade Spartan-3, the complete data path including three general
registers and the multiplexers for the adder inputs runs at over 50 MHz.

Best regards,
Eric

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Re: Strange syntax - Eric Smith - Dec 20 22:20:08 2007

Richard wrote:
> No doubt you are right about eventually having to design a proper
> adder.

Just in case I wasn't clear, I think using the addition operator
from IEEE.numeric_std (possibly wrapped in a function to make it
work on std_logic_vector) is a fine way to build an adder; in fact,
unless you have very specialized requirements, I wouldn't advise
doing it any other way.

What I'm really getting at is that you probably will need to
deal with the structure that gets data into and out of your adder(s),
unless you really don't mind having a large number of them chewing
up CLBs.

The most obvious thing is that if a block is going to compute a
sum and generate a carry out, don't use two instances of the "+"
operator to do it. Use one nine-bit adder like you've already
described, assign its output to a nine-bit signal, and use the low
eight bits as the sum and the ninth bit as the carry out.

But you probably already knew that.

Best regards,
Eric

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Strange syntax - rtstofer - Dec 21 3:05:40 2007

--- In f...@yahoogroups.com, "Eric Smith" wrote:
>
> Richard wrote:
> > No doubt you are right about eventually having to design a proper
> > adder.
>
> Just in case I wasn't clear, I think using the addition operator
> from IEEE.numeric_std (possibly wrapped in a function to make it
> work on std_logic_vector) is a fine way to build an adder; in fact,
> unless you have very specialized requirements, I wouldn't advise
> doing it any other way.
>
> What I'm really getting at is that you probably will need to
> deal with the structure that gets data into and out of your adder(s),
> unless you really don't mind having a large number of them chewing
> up CLBs.
>
> The most obvious thing is that if a block is going to compute a
> sum and generate a carry out, don't use two instances of the "+"
> operator to do it. Use one nine-bit adder like you've already
> described, assign its output to a nine-bit signal, and use the low
> eight bits as the sum and the ninth bit as the carry out.
>
> But you probably already knew that.
>
> Best regards,
> Eric
>
For this project, the structure around the adder is fairly simple.
One input is always the accumulator and the other has a MUX with the
usual suspects: +1, -1, 0 or another 8 bit operand or its' inverse.
The carry-in is controlled in the usual way.

On the POP-11 project, the author went to great lengths to build 4 bit
full lookahead adders with outputs for carry, zero, negative and
overflow. These were extended to get to 16 bits. The nice thing
about the adders: the flags were generated at the same time as the
result. It wasn't necessary to wait for the result to be completely
generated before working on the flags and flags were generated for
both 8 and 16 bit operations.

Using the '+' operator gives no flags (directly) and the library adder
doesn't generate the zero or negative flags. Maybe doing it the old
fashion way with logic for propogate and generate terms is the way to go.

For the moment, I just added more vectors for the temporary results.
Once the processor is running I'll go back and replace the ALU.

The projects comes from
http://www.amazon.com/Definitive-Guide-How-Computers-Math/dp/0471732788
and the processor is a fairly simple 8 bit design. I thought I would
build it for giggles and then port a version of 8k Basic instead of
the project ROM monitor.

Richard

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Re: Strange syntax - Kolja Sulimma - Dec 21 4:11:39 2007

Also note, that most FPGAs have the carry logic after the LUTs (and after
the special Muxes).
It is very hard for the synthesis tools to move logic accross the carry
logic.
Therefore the following code is likely to create to adders followed by a mux
and requires three luts
per bit with two routing delays:
result <= a+b when opcode=add else
a-b;

A better way is to do as much as possible in front of the adders so that the
logic can be merged with the
adder logic. The following code uses one LUT per bit and no routing delays:

temp <= b when opcode = add else
not b;
cin <= X"00" when opcode = add else
X"01";
result <= a+b+cin;

This way you can do up to four operation of the same bits in a single LUT.

Kolja

2007/12/21, rtstofer :
>
> --- In f...@yahoogroups.com , "Eric
> Smith" wrote:
> <>
> >> What I'm really getting at is that you probably will need to
> >> deal with the structure that gets data into and out of your adder(s),
> >> unless you really don't mind having a large number of them chewing
> >> up CLBs.
> >>
> >> The most obvious thing is that if a block is going to compute a
> >> sum and generate a carry out, don't use two instances of the "+"
> >> operator to do it. Use one nine-bit adder like you've already
> >> described, assign its output to a nine-bit signal, and use the low
> >> eight bits as the sum and the ninth bit as the carry out.
> > For this project, the structure around the adder is fairly simple.
> > One input is always the accumulator and the other has a MUX with the
> > usual suspects: +1, -1, 0 or another 8 bit operand or its' inverse.
> >The carry-in is controlled in the usual way.
>
[Non-text portions of this message have been removed]

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Strange syntax - rtstofer - Dec 21 10:46:31 2007

--- In f...@yahoogroups.com, "Kolja Sulimma" wrote:
>
> Also note, that most FPGAs have the carry logic after the LUTs (and
after
> the special Muxes).
> It is very hard for the synthesis tools to move logic accross the carry
> logic.
> Therefore the following code is likely to create to adders followed
by a mux
> and requires three luts
> per bit with two routing delays:
> result <= a+b when opcode=add else
> a-b;
>
> A better way is to do as much as possible in front of the adders so
that the
> logic can be merged with the
> adder logic. The following code uses one LUT per bit and no routing
delays:
>
> temp <= b when opcode = add else
> not b;
> cin <= X"00" when opcode = add else
> X"01";
> result <= a+b+cin;
>
> This way you can do up to four operation of the same bits in a
single LUT.
>
> Kolja

Thanks for this! The code, as written, is more like the first example.

I had noticed the LUT implementation but I must admit to not spending
a lot of time thinking about it. It's time to hit the books!

Richard

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Re: Strange syntax - Eric Smith - Dec 21 17:15:22 2007

Richard wrote:
> On the POP-11 project, the author went to great lengths to build 4 bit
> full lookahead adders with outputs for carry, zero, negative and
> overflow. These were extended to get to 16 bits. The nice thing
> about the adders: the flags were generated at the same time as the
> result. It wasn't necessary to wait for the result to be completely
> generated before working on the flags and flags were generated for
> both 8 and 16 bit operations.

I'm extremely dubious that they managed to generate the zero flag as fast
as they generate the actual sum or difference.

Your description suggests that they use separate n-bit and n+1-bit adders
to generate the sum and the carry out, but that won't be any faster than
using a single n+1-bit adder to generate both. The same is true for
the negative output (which is just the MSB of the sum). Overflow is
slightly more tricky, and will generally add at least one gate delay
above the time to compute the sum. The zero flag will take the
prop delay of the adder plus the prop delay of a 16-bit NOR gate.

There is no obvious way that using more than one n+1-1 bit adder can
make any of this faster in an FPGA, because for relatively narrow
word widths, using fancier adders will be slower than a ripple-carry
adder using the dedicated carry chain.

> Maybe doing it the old
> fashion way with logic for propogate and generate terms is the way to go.

Maybe for a wider adder (e.g., in an FPU), but not for a 17-bit adder
for the ALU.

Eric

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Re: Strange syntax - Eric Smith - Dec 21 21:00:02 2007

Richard wrote:
> One thing that is necessary is to get the handle the aux carry from
> the low nibble.

Attached below you will find what I used for a similar data path. I've
hacked out a lot of stuff to make it a simple example, so it's possible
that I've broken it in the process.

The main adder has ten bits (two more than the 8-bit word size) making
it possible to efficiently generate both carry and overflow outputs.

This uses a separate adder to derive the digit carry. It's possible
that less FPGA resources would be required if I'd instead used a
five-bit adder for the low part, and a six-bit adder for the high
part, and propogated the carry, but I wasn't sure that XST would
be able to infer that I really wanted a single ten-bit adder with
a tap from the digit carry. If it used separate adders with a
split carry chain it would be slower.

Eric
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.ALL;

-- 8 bit adder/subtracter with flag outputs
-- For subtraction, the carry inputs and outputs
-- are "not borrow" signals.
-- For add without carry in, set c_in to '0'.
-- For subtract without borrow in, set c_in to '1'.
entity alu8 is
port (a: in std_logic_vector (7 downto 0);
b: in std_logic_vector (7 downto 0);
c_in: in std_logic;
sub: in std_logic;
s: out std_logic_vector (7 downto 0);
c4_out: out std_logic;
c8_out: out std_logic;
n: out std_logic;
v: out std_logic;
z: out std_logic);
end alu8;

architecture rtl of alu8 is
signal bc: std_logic_vector (7 downto 0);
signal s10: unsigned (9 downto 0);
signal s5: unsigned (4 downto 0);
begin
-- complementer for subtraction
bc <= not b when sub = '1'
else b;

-- main adder - sign extend operands to 9 bits to simplify overflow
-- detection, and extend with a tenth bit of '0' to capture carry out
s10 <= unsigned ('0' & a (7) & a)
+ unsigned ('0' & bc (7) & bc)
+ unsigned'(0 => c_in);

-- extra adder to optimize digit carry output
s5 <= unsigned ('0' & a (3 downto 0))
+ unsigned ('0' & bc (3 downto 0));

-- outputs
s <= std_logic_vector (s10 (7 downto 0));
c4_out <= s5 (4);
c8_out <= s10 (9);
n <= s10 (7);
z <= '1' when s10 (7 downto 0) = (s'range => '0')
else '0';
v <= s10 (8) xor s10 (7);
end rtl;

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: Strange syntax - rtstofer - Dec 22 7:45:38 2007

>From the POP-11 project, here is the code for the 4 bit adder:

entity CLA4 is
Port ( do : in STD_LOGIC;
ci : in STD_LOGIC;
b : in STD_LOGIC_VECTOR (3 downto 0);
a : in STD_LOGIC_VECTOR (3 downto 0);
c : out STD_LOGIC;
v : out STD_LOGIC;
z : out STD_LOGIC;
n : out STD_LOGIC;
result : out STD_LOGIC_VECTOR (3 downto 0);
pm : out STD_LOGIC;
gm : out STD_LOGIC);
end CLA4;

architecture Behavioral of CLA4 is

signal p3, p2, p1, p0 : std_logic;
signal g3, g2, g1, g0 : std_logic;
signal c3, c2, c1, c0 : std_logic;

begin

p3 <= a(3) xor b(3);
p2 <= a(2) xor b(2);
p1 <= a(1) xor b(1);
p0 <= a(0) xor b(0);

g3 <= a(3) and b(3);
g2 <= a(2) and b(2);
g1 <= a(1) and b(1);
g0 <= a(0) and b(0);

c3 <= g3 or (p3 and g2) or (p3 and p2 and g1) or
(p3 and p2 and p1 and g0) or (p3 and p2 and p1 and p0 and ci);

c2 <= g2 or (p2 and g1) or (p2 and p1 and g0) or
(p2 and p1 and p0 and ci);

c1 <= g1 or (p1 and g0) or (p1 and p0 and ci);

c0 <= g0 or (p0 and ci);

pm <= p3 and p2 and p1 and p0;
gm <= g3 or (p3 and g2) or (p3 and p2 and g1) or (p3 and p2 and p1
and g0);

c <= c3;
v <= c2;
z <= (((not(p3 xor c2)) and (not(p2 xor c1))) and
(not(p1 xor c0))) and (not(p0 xor ci));
n <= p3 xor c2;
result <= (p3 xor c2) & (p2 xor c1) & (p1 xor c0) & (p0 xor ci);

end Behavioral;

These were then extended to form a 16 bit adder with flags available
for 8 bit operations:

entity CLA16 is
Port ( do : in STD_LOGIC;
byte : in STD_LOGIC;
ci : in STD_LOGIC;
b : in STD_LOGIC_VECTOR (15 downto 0);
a : in STD_LOGIC_VECTOR (15 downto 0);
result : out STD_LOGIC_VECTOR (15 downto 0);
c : out STD_LOGIC;
v : out STD_LOGIC;
z : out STD_LOGIC;
n : out STD_LOGIC);
end CLA16;

architecture Behavioral of CLA16 is

signal word : std_logic;
signal c3, c7, c11, c15 : std_logic;
signal gm0, gm1, gm2, gm3 : std_logic;
signal pm0, pm1, pm2, pm3 : std_logic;
signal ad0_ci, ad0_v, ad0_z, ad0_n, ad0_c : std_logic;
signal ad1_ci, ad1_v, ad1_z, ad1_n, ad1_c : std_logic;
signal ad2_ci, ad2_v, ad2_z, ad2_n, ad2_c : std_logic;
signal ad3_ci, ad3_v, ad3_z, ad3_n, ad3_c : std_logic;

begin

word <= not byte; -- word or byte operations

ad0_ci <= ci;
ad1_ci <= c3;
ad2_ci <= c7;
ad3_ci <= c11;

c3 <= gm0 or (pm0 and ci);
c7 <= gm1 or (pm1 and gm0) or (pm1 and pm0 and ci);
c11 <= gm2 or (pm2 and gm1) or (pm2 and pm1 and gm0) or
(pm2 and pm1 and pm0 and ci);
c15 <= gm3 or (pm3 and gm2) or (pm3 and pm2 and gm1) or
(pm3 and pm2 and pm1 and gm0) or
(pm3 and pm2 and pm1 and pm0 and ci);

c <= do and ((c7 and byte) or (c15 and word));

v <= do and (((ad1_v xor c7) and byte) or ((ad3_v xor c15) and
word));

z <= do and ((ad1_z and ad0_z and byte) or (ad3_z and ad2_z and
ad1_z and ad0_z and word));

n <= do and ((ad1_n and byte) or (ad3_n and word));

Inst_CLA4_0: entity work.CLA4 PORT MAP(
do => do,
ci => ad0_ci,
b => b(3 downto 0),
a => a(3 downto 0),
c => ad0_c,
v => ad0_v,
z => ad0_z,
n => ad0_n,
result => result(3 downto 0),
pm => pm0,
gm => gm0
);
-- and so on for the other 3 4-bit adders

end Behavioral;

In the end, it is much ado about nothing. At a minimum there is a
complete fetch cycle before accurate flags are required. This small
CPU has no pipeline.

One thing that is necessary is to get the handle the aux carry from
the low nibble.

Richard

To post a message, send it to: f...@yahoogroups.com
To unsubscribe, send a blank message to: f...@yahoogroups.com



(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )