Coding style

G

Guest

Hi,

Does anyone happen to know what will the following (software) code will look
like after going through a synthesis tool? I was told, back in the school,
that never use *HDL as a software language and should have a block diagram or
data path before coding. But it seams that more and more people trust the
synthesis tool rather.

// Verilog version
reg [5:0] offset; // input
reg [15:0] we; // input
reg [15:0] data_in[127:0]; // input

reg [7:0] data_out [63:0]; // output

wire [5:0] offset0; // internal logic
wire [5:0] offset1; // internal logic
....
wire [5:0] offset15; // internal logic

assign offset0 = offset;
assign offset1 = offset + 1;
....
assign offset15 = offset + 15;

always @ (posedge clk) begin
if (reset) begin
// initial code here
...
end begin
if (we[0]) data[offset0] <= data_in[7:0];
if (we[1]) data[offset1] <= data_in[15:8];
...
if (we[15]) data[offset15] <= data_in[127:120];
end
end

-- VHDL version
type data_type is array (63 downto 0) of std_logic_vector(7 downto 0);

signal offset : std_logic_vector(5 downto 0); -- input
signal we : std_logic_vector (15 downto 0); -- input
signal data_in : std_logic_vector (127 downto 0); -- input

signal data_out : data_type; -- output

signal offset0 : std_logic_vector(5 downto 0); -- internal logic
signal offset1 : std_logic_vector(5 downto 0); -- internal logic
....
signal offset15 : std_logic_vector(5 downto 0); -- internal logic

offset0 <= offset;
offset1 <= offset + 1;
....
offset15 <= offset + 15;

process (clk, reset)
if rising_edge(clk) then
if (reset = '1') then
-- initial code here
...
else
if (we(0)='1') then data(offset0) <= data_in(7 downto 0); end if;
if (we(1)='1') then data(offset0) <= data_in(15 downto 8); end if;
...
if (we(15)='1') then data(offset0) <= data_in(127 downto 120); end if;
end if;
end if;
end process;

If I was to implement the above circuit, I will not write the above codes. I
will first draw a data path diagram which show me that I can have have a
barrel shifter to map the 16-bit 'we' to 64-bit 'data_we' based on the
'offset' input. Than I will use another shifter to "expand" the data and
assign each of the 64 slots based on the 'data_we'. I may even write a simple
Perl script to generate this 64 statement.

Does anyone know any better implementation scheme or any synthesis tools that
will generate a better result base on the above code? I tried Xilinx XST and
the above code failed (out of memory ?!) I know some other synthesis tool can
generated a valid circuit with terrible performance.

The most important question is, "Should I worry about this?" Someone told me
that the code failed to compile just because XST is not good enough. But I
wonder. My teammates and me have a different point of view in CAD tools. They
believe the logic optimization (e.g. from behavioral description to netlist)
and don't trust the physical optimization (e.g. they do hand placement and
timing on every net). I believe the opposite.

There are too many *information* available when running the placement and
routing process which is NOT suitable for a human brain. But the tools can
handle this well. There some *knowledge* in the design which is hard to be
captured in the tools. And we engineerings are trained to use this knowledge
to optimize our design. So I believe that we should code more careful rather
than pumping constraints to the tools.

But the current trend is (at least observed by myself), to encourages users
code more like in a software environment. Is this the design flow for tomorrow
or I misunderstand something?
 
M

Mike Treseler

Does anyone happen to know what will the following (software) code will look
like after going through a synthesis tool?

Unless you have run a simulation testbench,
the output will likely be a syntax or logical error.
If the code doesn't sim like you expect,
why would you care what the synthesis output looks like?
I was told, back in the school,
that never use *HDL as a software language and should have a block diagram or
data path before coding.

If you don't mind variables and large processes,
algorithmic logic descriptions are possible.
If you prefer netlists use a process per block.
But it seams that more and more people trust the
synthesis tool rather.

Trust but verify.
View the rtl schematic output from synthesis.
Develop your own design rules.
The most important question is, "Should I worry about this?" Someone told me
that the code failed to compile just because XST is not good enough.

I expect that it failed for lack
of simulation and debug.
But the current trend is (at least observed by myself), to encourages users
code more like in a software environment. Is this the design flow for tomorrow
or I misunderstand something?

That is up to you.
Here are some single process examples to consider:
http://home.comcast.net/~mike_treseler/
Try it and see.


-- Mike Treseler
 
A

Andy

In your vhdl code, I assume you meant not to always store the data at
offset0.

Also, data is an array, and must be indexed by integers, not slv. That
is a certain error in synthesis or simulation.

Try:

for i in we'range loop
if we(i) = '1' then
data(i+offset) <= data_in(i*8+7 downto i*8);
end if;
end loop;

If we is mutually exclusive, then a good synthesis tool will infer ram
for data if you code it as such (priority encode, or better, pick up
the address before you decode the write strobes if possible, since the
binary address is ME by definition)

Assuming we is ME, you could add an exit statement after the assignment
inside the loop to speed up sim and not change the behavior.

Hope this helps,

Andy


Hi,

Does anyone happen to know what will the following (software) code will look
like after going through a synthesis tool? I was told, back in the school,
that never use *HDL as a software language and should have a block diagram or
data path before coding. But it seams that more and more people trust the
synthesis tool rather.

// Verilog version
reg [5:0] offset; // input
reg [15:0] we; // input
reg [15:0] data_in[127:0]; // input

reg [7:0] data_out [63:0]; // output

wire [5:0] offset0; // internal logic
wire [5:0] offset1; // internal logic
...
wire [5:0] offset15; // internal logic

assign offset0 = offset;
assign offset1 = offset + 1;
...
assign offset15 = offset + 15;

always @ (posedge clk) begin
if (reset) begin
// initial code here
...
end begin
if (we[0]) data[offset0] <= data_in[7:0];
if (we[1]) data[offset1] <= data_in[15:8];
...
if (we[15]) data[offset15] <= data_in[127:120];
end
end

-- VHDL version
type data_type is array (63 downto 0) of std_logic_vector(7 downto 0);

signal offset : std_logic_vector(5 downto 0); -- input
signal we : std_logic_vector (15 downto 0); -- input
signal data_in : std_logic_vector (127 downto 0); -- input

signal data_out : data_type; -- output

signal offset0 : std_logic_vector(5 downto 0); -- internal logic
signal offset1 : std_logic_vector(5 downto 0); -- internal logic
...
signal offset15 : std_logic_vector(5 downto 0); -- internal logic

offset0 <= offset;
offset1 <= offset + 1;
...
offset15 <= offset + 15;

process (clk, reset)
if rising_edge(clk) then
if (reset = '1') then
-- initial code here
...
else
if (we(0)='1') then data(offset0) <= data_in(7 downto 0); end if;
if (we(1)='1') then data(offset0) <= data_in(15 downto 8); end if;
...
if (we(15)='1') then data(offset0) <= data_in(127 downto 120); end if;
end if;
end if;
end process;

If I was to implement the above circuit, I will not write the above codes. I
will first draw a data path diagram which show me that I can have have a
barrel shifter to map the 16-bit 'we' to 64-bit 'data_we' based on the
'offset' input. Than I will use another shifter to "expand" the data and
assign each of the 64 slots based on the 'data_we'. I may even write a simple
Perl script to generate this 64 statement.

Does anyone know any better implementation scheme or any synthesis tools that
will generate a better result base on the above code? I tried Xilinx XST and
the above code failed (out of memory ?!) I know some other synthesis tool can
generated a valid circuit with terrible performance.

The most important question is, "Should I worry about this?" Someone told me
that the code failed to compile just because XST is not good enough. But I
wonder. My teammates and me have a different point of view in CAD tools. They
believe the logic optimization (e.g. from behavioral description to netlist)
and don't trust the physical optimization (e.g. they do hand placement and
timing on every net). I believe the opposite.

There are too many *information* available when running the placement and
routing process which is NOT suitable for a human brain. But the tools can
handle this well. There some *knowledge* in the design which is hard to be
captured in the tools. And we engineerings are trained to use this knowledge
to optimize our design. So I believe that we should code more careful rather
than pumping constraints to the tools.

But the current trend is (at least observed by myself), to encourages users
code more like in a software environment. Is this the design flow for tomorrow
or I misunderstand something?
 
G

Guest

Hi - Thanks for the info. There are many typo in the my post since the
original Verilog code is not allowed to be published. So I must hand
type a different code in the post. This lead to the logical error you
refered to. The original code can be simulate and is functional correct.
It can even be synthesized using tools rather than XST. My main point is
the coding style. Thanks anyway.
 
G

Guest

Andy said:
In your vhdl code, I assume you meant not to always store the data at
offset0. yes, that's a typo

Also, data is an array, and must be indexed by integers, not slv. That
is a certain error in synthesis or simulation.

Try:

for i in we'range loop
if we(i) = '1' then
data(i+offset) <= data_in(i*8+7 downto i*8);
end if;
end loop;
Thanks. I just learnt how to do this in Verilog using a "+:" operator. I
did not try the VHDL code yet.
If we is mutually exclusive, then a good synthesis tool will infer ram
for data if you code it as such (priority encode, or better, pick up
the address before you decode the write strobes if possible, since the
binary address is ME by definition)

Assuming we is ME, you could add an exit statement after the assignment
inside the loop to speed up sim and not change the behavior. not, 'we' can be any value

Hope this helps,

Andy


Hi,

Does anyone happen to know what will the following (software) code will look
like after going through a synthesis tool? I was told, back in the school,
that never use *HDL as a software language and should have a block diagram or
data path before coding. But it seams that more and more people trust the
synthesis tool rather.

// Verilog version
reg [5:0] offset; // input
reg [15:0] we; // input
reg [15:0] data_in[127:0]; // input

reg [7:0] data_out [63:0]; // output

wire [5:0] offset0; // internal logic
wire [5:0] offset1; // internal logic
...
wire [5:0] offset15; // internal logic

assign offset0 = offset;
assign offset1 = offset + 1;
...
assign offset15 = offset + 15;

always @ (posedge clk) begin
if (reset) begin
// initial code here
...
end begin
if (we[0]) data[offset0] <= data_in[7:0];
if (we[1]) data[offset1] <= data_in[15:8];
...
if (we[15]) data[offset15] <= data_in[127:120];
end
end

-- VHDL version
type data_type is array (63 downto 0) of std_logic_vector(7 downto 0);

signal offset : std_logic_vector(5 downto 0); -- input
signal we : std_logic_vector (15 downto 0); -- input
signal data_in : std_logic_vector (127 downto 0); -- input

signal data_out : data_type; -- output

signal offset0 : std_logic_vector(5 downto 0); -- internal logic
signal offset1 : std_logic_vector(5 downto 0); -- internal logic
...
signal offset15 : std_logic_vector(5 downto 0); -- internal logic

offset0 <= offset;
offset1 <= offset + 1;
...
offset15 <= offset + 15;

process (clk, reset)
if rising_edge(clk) then
if (reset = '1') then
-- initial code here
...
else
if (we(0)='1') then data(offset0) <= data_in(7 downto 0); end if;
if (we(1)='1') then data(offset0) <= data_in(15 downto 8); end if;
...
if (we(15)='1') then data(offset0) <= data_in(127 downto 120); end if;
end if;
end if;
end process;

If I was to implement the above circuit, I will not write the above codes. I
will first draw a data path diagram which show me that I can have have a
barrel shifter to map the 16-bit 'we' to 64-bit 'data_we' based on the
'offset' input. Than I will use another shifter to "expand" the data and
assign each of the 64 slots based on the 'data_we'. I may even write a simple
Perl script to generate this 64 statement.

Does anyone know any better implementation scheme or any synthesis tools that
will generate a better result base on the above code? I tried Xilinx XST and
the above code failed (out of memory ?!) I know some other synthesis tool can
generated a valid circuit with terrible performance.

The most important question is, "Should I worry about this?" Someone told me
that the code failed to compile just because XST is not good enough. But I
wonder. My teammates and me have a different point of view in CAD tools. They
believe the logic optimization (e.g. from behavioral description to netlist)
and don't trust the physical optimization (e.g. they do hand placement and
timing on every net). I believe the opposite.

There are too many *information* available when running the placement and
routing process which is NOT suitable for a human brain. But the tools can
handle this well. There some *knowledge* in the design which is hard to be
captured in the tools. And we engineerings are trained to use this knowledge
to optimize our design. So I believe that we should code more careful rather
than pumping constraints to the tools.

But the current trend is (at least observed by myself), to encourages users
code more like in a software environment. Is this the design flow for tomorrow
or I misunderstand something?
 
M

Mike Treseler

Hi - Thanks for the info. There are many typo in the my post since the
original Verilog code is not allowed to be published. So I must hand
type a different code in the post. This lead to the logical error you
refered to. The original code can be simulate and is functional correct.
It can even be synthesized using tools rather than XST. My main point is
the coding style. Thanks anyway.

You're welcome anyway.
Sorry if I missed your point.
Since everyone has different tools I think
"try it and see" is good advice.
I run small benchmark entities through synthesis
all the time to trade off fmax and utilization,
and to test my own design rules.
Good luck.

-- Mike Treseler
 
R

Rob Dekker

Hi
Not a full solution, but some tips :

The way your model is writte, a lot of data can be pushed around simultaniously.
That means that in hardware, there is a lot of logic needed.
What you want to check is which data can move simultaniously.

For example, can multiple bits from 'we' be high at the same time ?
If not (if only one bit is high simultaniously), then you can change the
16 variable assignments into a single one. That saves a lot of logic.
With that, data_in no longer needs simultanious access to all its (2048) bits.
So, you might be able to get it into a single RAMs.

Also, consider if you really need random access to all bits of 'data_out' ('data' in your target assignments).
If not, 'data_out' could also be implemented as a RAM, or as 16 small RAMs
(depending on which parts of 'data' need random access).

Write HDL with the target hardware in mind, and then follow the 'coding rules'
(for your synthesis tool) to write generic HDL that will get you that hardware.

Rob


Hi,

Does anyone happen to know what will the following (software) code will look
like after going through a synthesis tool? I was told, back in the school,
that never use *HDL as a software language and should have a block diagram or
data path before coding. But it seams that more and more people trust the
synthesis tool rather.

// Verilog version
reg [5:0] offset; // input
reg [15:0] we; // input
reg [15:0] data_in[127:0]; // input

reg [7:0] data_out [63:0]; // output

wire [5:0] offset0; // internal logic
wire [5:0] offset1; // internal logic
...
wire [5:0] offset15; // internal logic

assign offset0 = offset;
assign offset1 = offset + 1;
...
assign offset15 = offset + 15;

always @ (posedge clk) begin
if (reset) begin
// initial code here
...
end begin
if (we[0]) data[offset0] <= data_in[7:0];
if (we[1]) data[offset1] <= data_in[15:8];
...
if (we[15]) data[offset15] <= data_in[127:120];
end
end

-- VHDL version
type data_type is array (63 downto 0) of std_logic_vector(7 downto 0);

signal offset : std_logic_vector(5 downto 0); -- input
signal we : std_logic_vector (15 downto 0); -- input
signal data_in : std_logic_vector (127 downto 0); -- input

signal data_out : data_type; -- output

signal offset0 : std_logic_vector(5 downto 0); -- internal logic
signal offset1 : std_logic_vector(5 downto 0); -- internal logic
...
signal offset15 : std_logic_vector(5 downto 0); -- internal logic

offset0 <= offset;
offset1 <= offset + 1;
...
offset15 <= offset + 15;

process (clk, reset)
if rising_edge(clk) then
if (reset = '1') then
-- initial code here
...
else
if (we(0)='1') then data(offset0) <= data_in(7 downto 0); end if;
if (we(1)='1') then data(offset0) <= data_in(15 downto 8); end if;
...
if (we(15)='1') then data(offset0) <= data_in(127 downto 120); end if;
end if;
end if;
end process;

If I was to implement the above circuit, I will not write the above codes. I
will first draw a data path diagram which show me that I can have have a
barrel shifter to map the 16-bit 'we' to 64-bit 'data_we' based on the
'offset' input. Than I will use another shifter to "expand" the data and
assign each of the 64 slots based on the 'data_we'. I may even write a simple
Perl script to generate this 64 statement.

Does anyone know any better implementation scheme or any synthesis tools that
will generate a better result base on the above code? I tried Xilinx XST and
the above code failed (out of memory ?!) I know some other synthesis tool can
generated a valid circuit with terrible performance.

The most important question is, "Should I worry about this?" Someone told me
that the code failed to compile just because XST is not good enough. But I
wonder. My teammates and me have a different point of view in CAD tools. They
believe the logic optimization (e.g. from behavioral description to netlist)
and don't trust the physical optimization (e.g. they do hand placement and
timing on every net). I believe the opposite.

There are too many *information* available when running the placement and
routing process which is NOT suitable for a human brain. But the tools can
handle this well. There some *knowledge* in the design which is hard to be
captured in the tools. And we engineerings are trained to use this knowledge
to optimize our design. So I believe that we should code more careful rather
than pumping constraints to the tools.

But the current trend is (at least observed by myself), to encourages users
code more like in a software environment. Is this the design flow for tomorrow
or I misunderstand something?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top