Problem with additions and std_logic

This is a discussion on Problem with additions and std_logic within the vhdl forums in Programming Languages category; Hi, I am having a quite strange problem when I am using the addition with std_logic types. I am basically using a std_logic_vector containing the address for accessing a SRAM. After writing an octect in the RAM I am adding 8 to the address for the next word. As I did not have the expecting design, I have displayed the content of the address vector and I have something ... strange. Here are the values I obtain : 0000 0000 1100 1000 1001 0000 0101 1000 0010 0000 1110 1000 1011 0000 0111 1000 0100 0000 0000 1000 1101 0000 ...

Go Back   Application Development Forum > Programming Languages > vhdl

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-03-2008, 03:03 PM
XSterna
Guest
 
Default Problem with additions and std_logic

Hi,

I am having a quite strange problem when I am using the addition with
std_logic types.

I am basically using a std_logic_vector containing the address for
accessing a SRAM. After writing an octect in the RAM I am adding 8 to
the address for the next word.

As I did not have the expecting design, I have displayed the content
of the address vector and I have something ... strange.

Here are the values I obtain :

0000 0000
1100 1000
1001 0000
0101 1000
0010 0000
1110 1000
1011 0000
0111 1000
0100 0000
0000 1000
1101 0000
etc

I can see something is quite correct with the 2^0 -> 2^5 bits but only
for a few time and the 2^6 & 2^7 bits are totally wrong.

I thought that it could come from the library I used but after
different tests it does not seem to be the problem. When I try for
exemple a LED_out <= "0000 0000" + 8; everything is correct ...

Here is the reduced portion of the concerning code. I have removed
some signals which does not concern the address mechanism.

------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_arith.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity RAM_controller is
port (CLK, Reset,flag_data_in: in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);

signal_on : in std_logic; -- 0 : mode transfert - 1 : mode signal
rw : in std_logic; -- 0 : ecriture - 1 : lecture

sram_io : inout std_logic_vector(15 downto 0);
sram_a : out std_logic_vector(17 downto 0);
LED_out : out std_logic_vector(7 downto 0);
);
end RAM_controller;

architecture arch_RAM_controller OF RAM_controller IS
type state_machine is(idle,RAM_read);
signal current_state, next_state : state_machine;
signal I : std_logic_vector(15 downto 0);
signal counter_write,counter_read : unsigned(7 downto 0);
signal counter_write_next,counter_read_next : unsigned(7 downto 0);
signal addr, addr_next : std_logic_vector(17 downto 0);
begin

process(CLK,Reset)
begin
if Reset='1' then
current_state<=idle;
counter_write <= (others => '0');
counter_read <= (others => '0');
count <= (others => '0');
addr <= (others => '0');
elsif (CLK'event and CLK='1') then
current_state<=next_state;
counter_read <= counter_read_next;
counter_write <= counter_write_next;
count <= count_next;
addr <= addr_next;
end if;
end process;

process(current_state,rw,flag_data_in,data_in)
begin
counter_read_next <= counter_read;
counter_write_next <= counter_write;
addr_next <= addr;

case current_state is

when idle=>
LED_out <= addr;
if rw = '0' then -- write
if flag_data_in = '1' then
next_state <= RAM_write;
else
next_state <= idle;
end if;
else
next_state <= idle;
end if;

when RAM_write=>--ecriture
LED_out <= addr;
sram_a <= addr;
sram_io <= "00000000" & data_in;
sram_we <= '0';
addr_next <= addr + 8;
counter_write_next <= counter_write + 1;
next_state <= idle;

end case;
end process;
end arch_RAM_controller;


---------------------------------------------
The flag_data_in is high when a word is transfered by a RS232 link
(the STOP state of the RS232 controller).

If anyone has an idea on this problem it would be great because I am
really clueless on that issue !

Xavier
Reply With Quote
  #2  
Old 08-03-2008, 03:29 PM
rickman
Guest
 
Default Re: Problem with additions and std_logic

On Aug 3, 3:03 pm, XSterna <XSte...@gmail.com> wrote:
> Hi,
>
> I am having a quite strange problem when I am using the addition with
> std_logic types.
>
> I am basically using a std_logic_vector containing the address for
> accessing a SRAM. After writing an octect in the RAM I am adding 8 to
> the address for the next word.
>
> As I did not have the expecting design, I have displayed the content
> of the address vector and I have something ... strange.
>
> Here are the values I obtain :
>
> 0000 0000
> 1100 1000
> 1001 0000
> 0101 1000
> 0010 0000
> 1110 1000
> 1011 0000
> 0111 1000
> 0100 0000
> 0000 1000
> 1101 0000
> etc
>
> I can see something is quite correct with the 2^0 -> 2^5 bits but only
> for a few time and the 2^6 & 2^7 bits are totally wrong.
>
> I thought that it could come from the library I used but after
> different tests it does not seem to be the problem. When I try for
> exemple a LED_out <= "0000 0000" + 8; everything is correct ...
>
> Here is the reduced portion of the concerning code. I have removed
> some signals which does not concern the address mechanism.
>
> ------------------------------------------------------------
>
> library IEEE;
> use IEEE.STD_LOGIC_1164.all;
> use IEEE.STD_LOGIC_arith.all;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
>
> entity RAM_controller is
> port (CLK, Reset,flag_data_in: in std_logic;
> data_in : in std_logic_vector(7 downto 0);
> data_out : out std_logic_vector(7 downto 0);
>
> signal_on : in std_logic; -- 0 : mode transfert - 1 : mode signal
> rw : in std_logic; -- 0 : ecriture - 1 : lecture
>
> sram_io : inout std_logic_vector(15 downto 0);
> sram_a : out std_logic_vector(17 downto 0);
> LED_out : out std_logic_vector(7 downto 0);
> );
> end RAM_controller;
>
> architecture arch_RAM_controller OF RAM_controller IS
> type state_machine is(idle,RAM_read);
> signal current_state, next_state : state_machine;
> signal I : std_logic_vector(15 downto 0);
> signal counter_write,counter_read : unsigned(7 downto 0);
> signal counter_write_next,counter_read_next : unsigned(7 downto 0);
> signal addr, addr_next : std_logic_vector(17 downto 0);
> begin
>
> process(CLK,Reset)
> begin
> if Reset='1' then
> current_state<=idle;
> counter_write <= (others => '0');
> counter_read <= (others => '0');
> count <= (others => '0');
> addr <= (others => '0');
> elsif (CLK'event and CLK='1') then
> current_state<=next_state;
> counter_read <= counter_read_next;
> counter_write <= counter_write_next;
> count <= count_next;
> addr <= addr_next;
> end if;
> end process;
>
> process(current_state,rw,flag_data_in,data_in)
> begin
> counter_read_next <= counter_read;
> counter_write_next <= counter_write;
> addr_next <= addr;
>
> case current_state is
>
> when idle=>
> LED_out <= addr;
> if rw = '0' then -- write
> if flag_data_in = '1' then
> next_state <= RAM_write;
> else
> next_state <= idle;
> end if;
> else
> next_state <= idle;
> end if;
>
> when RAM_write=>--ecriture
> LED_out <= addr;
> sram_a <= addr;
> sram_io <= "00000000" & data_in;
> sram_we <= '0';
> addr_next <= addr + 8;
> counter_write_next <= counter_write + 1;
> next_state <= idle;
>
> end case;
> end process;
> end arch_RAM_controller;
>
> ---------------------------------------------
> The flag_data_in is high when a word is transfered by a RS232 link
> (the STOP state of the RS232 controller).
>
> If anyone has an idea on this problem it would be great because I am
> really clueless on that issue !
>
> Xavier


The code seems overly complicated for what you are trying to do, but
the only thing I can see that might be a problem is the timing of the
two input signals, rw and flag_data_in. A write happens when rw is 0
and flag_data_in is 1. If this combination is asserted for more than
two clock cycles you will get multiple writes. I say two because the
first cycle with this asserted causes the state change and the inputs
are ignored for that cycle. On the third cycle the inputs are checked
again and if asserted a second write happens. This will continue as
long as the inputs are asserted.

Are you running a simulation? Look at the detailed timing of the
address. Does it change more than once rapidly? Or check the value
of counter_write. It will increment by 1 for each write. If that
changes by more than 1, your problem is the enable. Does the write
counter increment by 25 by any chance?

A lot of debugging can be done by the Sherlock Holmes method.
Eliminate whatever is impossible and that which is left must be the
truth. It looks like it is impossible for the increment by 8 to
change the address that way in one clock cycle. So it must be
happening in multiple clock cycles.

Rick
Reply With Quote
  #3  
Old 08-03-2008, 05:14 PM
KJ
Guest
 
Default Re: Problem with additions and std_logic


"XSterna" <XSterna@gmail.com> wrote in message
news:8d123d3e-ac86-45d0-86be-8e31918f261b@m44g2000hsc.googlegroups.com...
> Hi,
>
> I am having a quite strange problem when I am using the addition with
> std_logic types.
>


Off to a bad start....std_logic_vectors and addition...oh well.

> I am basically using a std_logic_vector containing the address for
> accessing a SRAM. After writing an octect in the RAM I am adding 8 to
> the address for the next word.
>


OK.

> As I did not have the expecting design, I have displayed the content
> of the address vector and I have something ... strange.
>


Displayed on what?
- Real hardware (possibly hardware issues or timing issues)
- Simulation (none of that nastiness).

> Here are the values I obtain :
>
> 0000 0000
> 1100 1000
> 1001 0000
> 0101 1000
> 0010 0000
> 1110 1000
> 1011 0000
> 0111 1000
> 0100 0000
> 0000 1000
> 1101 0000
> etc
>
> I can see something is quite correct with the 2^0 -> 2^5 bits but only
> for a few time and the 2^6 & 2^7 bits are totally wrong.
>


A simulation would likely clear this all up...

> I thought that it could come from the library I used


Yes, suspect everything else first...then question your own code and design.

> but after
> different tests it does not seem to be the problem.


Frequently that is the result...library is fine, so it must be the new and
untested, unvalidated design...go figure.

> When I try for
> exemple a LED_out <= "0000 0000" + 8; everything is correct ...
>



> Here is the reduced portion of the concerning code. I have removed
> some signals which does not concern the address mechanism.
>
> ------------------------------------------------------------
>
> library IEEE;
> use IEEE.STD_LOGIC_1164.all;
> use IEEE.STD_LOGIC_arith.all;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
>


Use ieee.numeric_std instead of std_logic_arith and std_logic_unsigned.
This isn't the cause of your problem, but numeric_std is an actual standard,
the others are not.

>
> entity RAM_controller is
> port (CLK, Reset,flag_data_in: in std_logic;
> data_in : in std_logic_vector(7 downto 0);
> data_out : out std_logic_vector(7 downto 0);
>
> signal_on : in std_logic; -- 0 : mode transfert - 1 : mode signal
> rw : in std_logic; -- 0 : ecriture - 1 : lecture
>
> sram_io : inout std_logic_vector(15 downto 0);
> sram_a : out std_logic_vector(17 downto 0);
> LED_out : out std_logic_vector(7 downto 0);
> );
> end RAM_controller;
>


I wonder where the read and write signals are? Oh well, you're only
interested in the address so far.

> architecture arch_RAM_controller OF RAM_controller IS
> type state_machine is(idle,RAM_read);
> signal current_state, next_state : state_machine;
> signal I : std_logic_vector(15 downto 0);
> signal counter_write,counter_read : unsigned(7 downto 0);
> signal counter_write_next,counter_read_next : unsigned(7 downto 0);
> signal addr, addr_next : std_logic_vector(17 downto 0);
> begin
>
> process(CLK,Reset)
> begin
> if Reset='1' then
> current_state<=idle;
> counter_write <= (others => '0');
> counter_read <= (others => '0');
> count <= (others => '0');
> addr <= (others => '0');
> elsif (CLK'event and CLK='1') then
> current_state<=next_state;
> counter_read <= counter_read_next;
> counter_write <= counter_write_next;
> count <= count_next;
> addr <= addr_next;
> end if;
> end process;
>


Synchronous process, so far so good.

> process(current_state,rw,flag_data_in,data_in)
> begin
> counter_read_next <= counter_read;
> counter_write_next <= counter_write;
> addr_next <= addr;
>
> case current_state is
>
> when idle=>
> LED_out <= addr;
> if rw = '0' then -- write
> if flag_data_in = '1' then
> next_state <= RAM_write;
> else
> next_state <= idle;
> end if;
> else
> next_state <= idle;
> end if;
>
> when RAM_write=>--ecriture
> LED_out <= addr;
> sram_a <= addr;
> sram_io <= "00000000" & data_in;
> sram_we <= '0';
> addr_next <= addr + 8;
> counter_write_next <= counter_write + 1;
> next_state <= idle;
>
> end case;
> end process;


Hmmm...you seem to be missing quite a few signals from the sensitivity list.
Quick perusal I see that 'counter_read', 'counter_write', 'addr',
'RAM_write' seem to be missing. This will create a difference between
simulation (if you did this) and synthesis. Synthesis should produce a
warning message to the effect that you have an incomplete sensitivity list
and list all of the above signals and say that it will be assuming that the
others should be added....sounds good, but like I said difference between
sim and actual very bad.

Options:
1. Add the signals and re-simulate
2. Get rid of the two processes and condense it into a single one and
retest. Splitting into a combinatorial process and a separate synchronous
process serves no purpose and creates problems such as:
- The incomplete sensitivity list which creates differences between real
world and simulation.
- Possible creation of latches if there is a signal that doesn't get
assigned for every path through I don't see any instances of this in your
posted code, but you also stripped it down for the posting so who knows.

> end arch_RAM_controller;
>
>
> ---------------------------------------------
> The flag_data_in is high when a word is transfered by a RS232 link
> (the STOP state of the RS232 controller).
>
> If anyone has an idea on this problem it would be great because I am
> really clueless on that issue !
>


Is the input signal 'rw' synchronous to the clk? More generally any input
to the entity most likely needs to be synchronous to clk, but 'rw' is
definitely being used in a way that would require it to be synchronous to
clk.

Have you simulated this?

Timing analysis completed successfully?

KJ


Reply With Quote
  #4  
Old 08-04-2008, 05:24 AM
Symon
Guest
 
Default Re: Problem with additions and std_logic

XSterna wrote:
>
> If anyone has an idea on this problem it would be great because I am
> really clueless on that issue !
>
> Xavier


http://www.synthworks.com/papers/vhd...mapld_2003.pdf


Reply With Quote
  #5  
Old 08-04-2008, 09:39 AM
XSterna
Guest
 
Default Re: Problem with additions and std_logic

I have sent an answer yesterday but it does not seem that it worked !
In fact rickman was right, I had a bad design with my flag_data_in
signal which was at the high state for more than one clock cycle. A
really 'basic' problem that shows actually that my design is not
really good, but I'm learning

So my actual problem is solved, but I still have others, now with the
read state ... I think I have to rebuild something cleaner and that is
why the advices you gave me are good for me

On 4 août, 10:24, "Symon" <symon_bre...@hotmail.com> wrote:
> XSterna wrote:
>
> > If anyone has an idea on this problem it would be great because I am
> > really clueless on that issue !

>
> > Xavier

>
> http://www.synthworks.com/papers/vhd...mapld_2003.pdf


In fact before posting here I read a previous message in this
newsgroup where this link was given. I read the part about the
libraries (that's why i talked about it) but when I am using
ieee.numeric_std I experienced some troubles when I run the
Synthesize. The actual definition of libraries is the only one which
seems to work with my code. With the ieee.numeric_std library i have
this error : "+ can not have such operands in this context." for the

addr_next <= addr + "1000";
counter_write_next <= counter_write + 1;

For a counter signal I read I could use an unsigned type but for the
address one I can't since it is a 'physical' signal and the unsigned
type does not work when I synthesize.

On 3 août, 22:14, "KJ" <kkjenni...@sbcglobal.net> wrote:
> > I am having a quite strange problem when I am using the addition with
> > std_logic types.

>
> Off to a bad start....std_logic_vectors and addition...oh well.


But I don't really get why it's not good to use std_logic_vectors. In
my beginner use, I just saw that I can't use an unsigned as an in or
out signal. But it's not that I don't want to use them, I just don't
know why I should and how


> > As I did not have the expecting design, I have displayed the content
> > of the address vector and I have something ... strange.

>
> Displayed on what?
> - Real hardware (possibly hardware issues or timing issues)
> - Simulation (none of that nastiness).


Sorry I forgot an information ! I was displaying it on LEDs to be able
to visualise it. In fact I usually simulate my designs with modelsim
but in that case, since I use a SRAM, I can't really simulate it. Part
of my concern is to know if the SRAM is well "read and written" and a
Modelsim simulation can not give me that.

> > I thought that it could come from the library I used

>
> Yes, suspect everything else first...then question your own code and design.


In my case it was because at first I did not have a library which
understood my '+' operation.

> Use ieee.numeric_std instead of std_logic_arith and std_logic_unsigned.
> This isn't the cause of your problem, but numeric_std is an actual standard,
> the others are not.


As i wrote previously in this message, I am having troubles with the
addr signal which is an 'out' one. With numeric_std I can't do a
addition with std_logic_vector but I need it as an output...

> > entity RAM_controller is
> > port (CLK, Reset,flag_data_in: in std_logic;
> > data_in : in std_logic_vector(7 downto 0);
> > data_out : out std_logic_vector(7 downto 0);

>
> > signal_on : in std_logic; -- 0 : mode transfert - 1 : mode signal
> > rw : in std_logic; -- 0 : ecriture - 1 : lecture

>
> > sram_io : inout std_logic_vector(15 downto 0);
> > sram_a : out std_logic_vector(17 downto 0);
> > LED_out : out std_logic_vector(7 downto 0);
> > );
> > end RAM_controller;

>
> I wonder where the read and write signals are? Oh well, you're only
> interested in the address so far.


In fact I wanted to lighten my code to focus on my addr problem. But I
now think for an experienced designer it would be better to have
everything to understand ...
I will give the entire code, but please bear in mind I am beginner


> Hmmm...you seem to be missing quite a few signals from the sensitivity list.
> Quick perusal I see that 'counter_read', 'counter_write', 'addr',
> 'RAM_write' seem to be missing. This will create a difference between
> simulation (if you did this) and synthesis. Synthesis should produce a
> warning message to the effect that you have an incomplete sensitivity list
> and list all of the above signals and say that it will be assuming that the
> others should be added....sounds good, but like I said difference between
> sim and actual very bad.


Yes they are missing ... and this is maybe why the rest of my design
is not working well. I will test it !

> Options:
> 1. Add the signals and re-simulate


When you say simulate do you think about modelsim for example ?
Because I as told before i don't really understand the good of a
simulation for the whole design (because for the adrr i agree i would
have see the problem !) since I can't have the 'real' SRAM signal.

> 2. Get rid of the two processes and condense it into a single one and
> retest. Splitting into a combinatorial process and a separate synchronous
> process serves no purpose and creates problems such as:
> - The incomplete sensitivity list which creates differences between real
> world and simulation.
> - Possible creation of latches if there is a signal that doesn't get
> assigned for every path through I don't see any instances of this in your
> posted code, but you also stripped it down for the posting so who knows.
>


In fact from the few lectures and books I had about FPGA and VHDL I
always found two different process with the reset and clk separted
from the rest. Do you mean that I should do everything on a same
process with the if rst and if clk at the beginning of it ?


> Is the input signal 'rw' synchronous to the clk? More generally any input
> to the entity most likely needs to be synchronous to clk, but 'rw' is
> definitely being used in a way that would require it to be synchronous to
> clk.


rw is a switch so it is not sunchronous to the clk. The Idea of my
design is to load a file to the SRAM. the rw switch is used to "rw =
0" write it to the RAM by RS232 ; "rw = 1" read it back by RS232 to
control to file is well written.

> Have you simulated this?
>
> Timing analysis completed successfully?


No I don't have any simulation on this. I am visualising the result of
it with LEDs and with the RS232 communication. It sounds really
artisanal but one again I did not find any other solution to really be
able to test the RAM.

Thanks a lot for your help and your time. If you are curious about my
design here is the entire code :

library IEEE;
use IEEE.STD_LOGIC_1164.all;
--use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_arith.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity RAM_controller is
port (CLK, Reset,flag_data_in: in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);

signal_on : in std_logic; -- 0 : mode transfert - 1 : mode signal
rw : in std_logic; -- 0 : ecriture - 1 : lecture
Flag_data_out : out std_logic;


sram_io : inout std_logic_vector(15 downto 0);
sram_a : out std_logic_vector(17 downto 0);
LED_out : out std_logic_vector(7 downto 0);
sram_ce : out std_logic;
sram_ub : out std_logic;
sram_lb : out std_logic;
sram_we : out std_logic;
sram_oe : out std_logic
);
end RAM_controller;

architecture arch_RAM_controller OF RAM_controller IS
type state_machine is(idle,RAM_read,RAM_write);
signal current_state, next_state : state_machine;
signal I : std_logic_vector(15 downto 0);
signal counter_write,counter_read : unsigned(7 downto 0);
signal counter_write_next,counter_read_next : unsigned(7 downto 0);
signal addr, addr_next : std_logic_vector(17 downto 0);
begin

process(CLK,Reset)
begin
if Reset='1' then
current_state<=idle;
counter_write <= (others => '0');
counter_read <= (others => '0');
addr <= (others => '0');
elsif (CLK'event and CLK='1') then
current_state<=next_state;
counter_read <= counter_read_next;
counter_write <= counter_write_next;
addr <= addr_next;
end if;
end process;


process(current_state,rw,flag_data_in,data_in,coun ter_write,counter_read,addr)
begin
counter_read_next <= counter_read;
counter_write_next <= counter_write;
addr_next <= addr;

sram_ce <= '0';
sram_a <= (others => '0');
sram_io <= (others => 'Z');
sram_ce <= '0';
sram_ub <= '1';
sram_lb <= '0';
sram_we <= '1';
sram_oe <= '1';
flag_data_out<='0';
data_out <= (others => '1');
case current_state is

when idle=>
--LED_out <= counter_write(3 downto 0)& counter_read(3 downto 0);
if rw = '0' then -- write
if flag_data_in = '1' then
next_state <= RAM_write;
else
next_state <= idle;
end if;
elsif rw = '1' then
addr_next <= (others => '0');

next_state <= RAM_read;
else
next_state <= idle;
end if;

when RAM_write=>--ecriture
--LED_out <= counter_write(3 downto 0)& counter_read(3 downto 0);
sram_a <= addr;
sram_io <= "00000000" & data_in;
sram_we <= '0';
addr_next <= addr + "1000";
counter_write_next <= counter_write + 1;

next_state <= idle;

when RAM_read=>--lecture
--LED_out <= counter_write(3 downto 0)& counter_read(3 downto 0);
if (counter_read < counter_write) then
sram_a <= addr;
sram_a <= (others => '0');
flag_data_out<='1';
sram_oe <= '0';
I <= sram_io;
data_out <= I(7 downto 0);
addr_next <= addr + 8;
counter_read_next <= counter_read + 1;
next_state <= RAM_read;
else
next_state <= idle;
end if;
end case;
end process;
end arch_RAM_controller;

Reply With Quote
  #6  
Old 08-04-2008, 11:12 AM
KJ
Guest
 
Default Re: Problem with additions and std_logic

>
> > XSterna wrote:

>
> In fact before posting here I read a previous message in this
> newsgroup where this link was given. I read the part about the
> libraries (that's why i talked about it) but when I am using
> ieee.numeric_std I experienced some troubles when I run the
> Synthesize. The actual definition of libraries is the only one which
> seems to work with my code. With the ieee.numeric_std library i have
> this error : "+ can not have such operands in this context." for the
>
> addr_next <= addr + "1000";
> counter_write_next <= counter_write + 1;
>


With addr and addr_next both being std_logic_vectors then you would...
addr_next <= std_logic_vector(unsigned(addr) + 8);

The reason for the error is that "1000" is ambiguous. YOU know that
you mean it to be a binary representation of the number 8, but it is
also the representation that would be used for -8. When adding/
subtracting constants, it is always much clearer to simply use
integers for the constants and not hard code in bit vectors.

> For a counter signal I read I could use an unsigned type but for the
> address one I can't since it is a 'physical' signal and the unsigned
> type does not work when I synthesize.
>


No, 'addr' is an internal signal to your architecture; 'sram_a' is the
entity output so that needs to be a std_logic_vector. Personally, I
would define 'addr' as

signal addr: unsigned(sram_a'range);

I wouldn't have an 'addr_next' signal at all (because of the upcoming
discussion on two versus one process) but if I did then the
previously mentioned addition would simplify to

addr_next <= addr + 8;

>
> But I don't really get why it's not good to use std_logic_vectors. In
> my beginner use, I just saw that I can't use an unsigned as an in or
> out signal.


It's not that you can't use unsigned as outputs, it is just that the
common practice is that the top level signals of a design should all
be std_logic/std_logic_vector.

> But it's not that I don't want to use them, I just don't
> know why I should and how
>


Why: When you do arithmetic, use unsigned (or signed...sometimes you
do need to signed arithmetic, like if you wanted to count down to -1
for some reason).

How: Simply declare the signal as unsigned (or signed) of the
appropriate width. Signed/unsigned vectors are really nothing more
than an interpretation of a collection of bits as having some numeric
value, whereas std_logic_vector is simply a collection of bits, there
is no inherent numeric value interpretation implied. When you had
trouble adding "1000" you mentally had this idea that "1000" is the
same thing as "8" because you wanted it to have a numeric
interpretation...but a collection of bits does not *have* to be viewed
in that manner, in fact since "1000" would just as easily be
interpreted as "-8" there is a problem.

When you do have some interface requirement for std_logic_vectors, it
does not prevent you from creating an internal signal (like 'addr')
that is of the appropriate type for usage and then when you're all
done add another concurrent statement that casts the signal to the
required type. In your case it would be

sram_a <= std_logic_vector(addr);

This statement converts the unsigned 'addr' into the std_logic_vector
'sram_a'. It costs zero hardware, no additional logic gets generated
to do this since 'unsigned' is simply a particular intepretation of a
collection of bits, and 'std_logic_vector' is simply a different
interpretation of the same collection of bits.

> > Displayed on what?
> > - Real hardware (possibly hardware issues or timing issues)
> > - Simulation (none of that nastiness).

>
> Sorry I forgot an information ! I was displaying it on LEDs to be able
> to visualise it. In fact I usually simulate my designs with modelsim
> but in that case, since I use a SRAM, I can't really simulate it. Part
> of my concern is to know if the SRAM is well "read and written" and a
> Modelsim simulation can not give me that.
>


You can simulate most anything, including the SRAM. There are likely
existing models for the SRAM you're using available on the web. Even
without such a model though, your posting was regarding the address
outputs to the SRAM you wouldn't need an SRAM model to see this.
Simulate.

> > > I thought that it could come from the library I used

>
> > Yes, suspect everything else first...then question your own code and design.

>
> In my case it was because at first I did not have a library which
> understood my '+' operation.
>


My point was that many blame the tools, libraries, or whatever
first...when they should be questioning their own code first.

>
> > Hmmm...you seem to be missing quite a few signals from the sensitivity list.
> > Quick perusal I see that 'counter_read', 'counter_write', 'addr',
> > 'RAM_write' seem to be missing. *This will create a difference between
> > simulation (if you did this) and synthesis. *Synthesis should producea
> > warning message to the effect that you have an incomplete sensitivity list
> > and list all of the above signals and say that it will be assuming thatthe
> > others should be added....sounds good, but like I said difference between
> > sim and actual very bad.

>
> Yes they are missing ... and this is maybe why the rest of my design
> is not working well. I will test it !
>


Good.

> > Options:
> > 1. Add the signals and re-simulate

>
> When you say simulate do you think about modelsim for example ?


Use whatever simulator you prefer.

> Because I as told before i don't really understand the good of a
> simulation for the whole design (because for the adrr i agree i would
> have see the problem !) since I can't have the 'real' SRAM signal.


Sure you can.

>
> > 2. Get rid of the two processes and condense it into a single one and
> > retest. *Splitting into a combinatorial process and a separate synchronous
> > process serves no purpose and creates problems such as:
> > - The incomplete sensitivity list which creates differences between real
> > world and simulation.
> > - Possible creation of latches if there is a signal that doesn't get
> > assigned for every path through * I don't see any instances of this in your
> > posted code, but you also stripped it down for the posting so who knows..

>
> In fact from the few lectures and books I had about FPGA and VHDL I
> always found two different process with the reset and clk separted
> from the rest.


The books and lectures are dispensing poor advice. Using a
combinatorial process and a separate synchronous process as you've
done leads to the possibility of the above mentioned design errors. A
good designer avoids methods that can lead to problems or that creates
extra work, therefore the dispensers of such knowledge would not be
considered good at design (in my opinion). Such books and lectures
though are common, so don't feel that you've been cheated, simply
question them directly if possible about the above two points and ask
how there method could in any way be considered superior to a method
that does not have such drawbacks?

> Do you mean that I should do everything on a same
> process with the if rst and if clk at the beginning of it ?
>


I usually use rst synchronously, but some prefer the async reset. So
I would use the following template
process(clk)
begin
if rising_edge(clk) then
if (rst = '1') then
...
else
...
end if;
end if;
end process;

For an async reset I would use the following template

process(clk,rst)
begin
if rising_edge(clk) then
...
end if;

if (rst = '1') then
...
else
...
end if;
end process;

Whether you use rst asynchronously or synchronously, you ALWAYS have
to use a *synchronized* rst signal (i.e. 'rst' wouldn't come from an
external input pin of the device, it would be the output of a flip
flop). The reason is that the trailing edge of 'rst' (i.e. when it
goes from active to inactive) needs to meet setup time requirements
relative to the rising edge of 'clk' otherwise, on the first clock
after 'rst' goes to '0' flip flops in the device could get into states
that you had not intended.

> > Is the input signal 'rw' synchronous to the clk? *More generally any input
> > to the entity most likely needs to be synchronous to clk, but 'rw' is
> > definitely being used in a way that would require it to be synchronous to
> > clk.

>
> rw is a switch so it is not sunchronous to the clk. The Idea of my
> design is to load a file to the SRAM. the rw switch is used to "rw =
> 0" write it to the RAM by RS232 ; "rw = 1" read it back by RS232 to
> control to file is well written.
>


Switches are known to bounce...for long periods of time. One press of
the switch can likely produce a whole slew of apparent switch
pushes...if you've never seen this it's fun to watch for the first
time...a pain then to have add debounce logic later. So...
1. Synchronize 'rw' to clk before using it for anything.
2. Be prepared to add debounce logic once you discover what switches
reeeeeally do.

> > Have you simulated this?

>
> > Timing analysis completed successfully?

>
> No I don't have any simulation on this. I am visualising the result of
> it with LEDs and with the RS232 communication. It sounds really
> artisanal but one again I did not find any other solution to really be
> able to test the RAM.


It's almost always easier to debug in simulation than on real
hardware. If nothing else, when you get to the real hardware you
should have more confidence that the design is functionally sound.
Having said that though, it appears that you also have real world
issues like switch debounce and asynchronous inputs that will be
coming up to bite you...and those do not show up in simulation.

>
> Thanks a lot for your help and your time.


You're welcome.

KJ
Reply With Quote
  #7  
Old 08-04-2008, 01:51 PM
Andy
Guest
 
Default Re: Problem with additions and std_logic

On Aug 4, 10:12 am, KJ <kkjenni...@sbcglobal.net> wrote:
> For an async reset I would use the following template
>
> process(clk,rst)
> begin
> if rising_edge(clk) then
> ...
> end if;
>
> if (rst = '1') then
> ...
> else
> ...
> end if;
> end process;


KJ has given very good advice, except there should not be an "else" in
the reset clause (I'm sure it was a typo). I use that template when I
want to have some storage devices be asynchronously reset, and others
in the same process not be asynchronously reset.

Otherwise, I use the more common async reset template:

process(clk,rst)
... -- declarations go here
begin
if (rst = '1') then
... -- reset assignments go here
elsif rising_edge(clk) then
... -- synchronous assignments go here
end if;
end process;

The only problem is that if you forget to include a register's signal/
variable in the reset assignments, the synthesis will (should) create
a feedback mux to ensure that the unreset register maintains its value
on clock cycles while the async reset is active, which creates timing
problems. Most synthesis tools will warn you that they are creating
the feedback mux, which is a hint that you left a reset assignment
out.

The following (corrected version of KJ's) template avoids that, but
also eliminates the warning if you unintentionally left a reset
assignment out. That's why I don't like using it unless I'm
intentionally leaving something unreset. Use of this template is a
reminder for me to double check the reset assignments.

process(clk,rst)
... -- declarations go here
begin
if rising_edge(clk) then
... -- synchronous assignments go here
end if;

if (rst = '1') then
... -- reset assignments go here
end if;
end process;

Andy
Reply With Quote
  #8  
Old 08-04-2008, 03:13 PM
KJ
Guest
 
Default Re: Problem with additions and std_logic

On Aug 4, 1:51*pm, Andy <jonesa...@comcast.net> wrote:
> On Aug 4, 10:12 am, KJ <kkjenni...@sbcglobal.net> wrote:
>
> KJ has given very good advice, except there should not be an "else" in
> the reset clause (I'm sure it was a typo).


Actually it was a copy/paste-o...or more specifically the lack of a
delete-o following the copy/paste rather than a typo...thanks for the
catch.

KJ
Reply With Quote
  #9  
Old 08-04-2008, 06:36 PM
XSterna
Guest
 
Default Re: Problem with additions and std_logic

Hi,

Thank you for the explanation about std_logic and unsigned. I
understand the "difference" and I will do my best to deal with it in a
better way.

About the switch, to be honnest I knew it but since my design seemed
to be working and I did not find my "old" debounce entity, I did not
used it. But I know I will need one to be sure everything is ok.

About the simulation, I began to build one for the RAM controller
because you are right it will be easier to debug and in fact the
"SRAM" is not really the one which seems to be problematic

Now, the main point I did not really understand is the "all-in-one"
process one. I understand the synchronous and asynchronous scheme in
what you wrote. But in my case I don't really catch how to implement
it.

The separation of the process allows me to manage the next state. I
don't really see how I will be able to manage the incrementation of a
signal for example the management of the addr signal. How to increment
by 8 ? with only one signal i don't see any solution since a <= addr ;
a<= addr + 8 will give me a <= addr +8 if it is in the same process.

Well I think I have to work on that because this is a really new
approach for me
Reply With Quote
  #10  
Old 08-04-2008, 07:01 PM
Mike Treseler
Guest
 
Default Re: Problem with additions and std_logic

XSterna wrote:

> The separation of the process allows me to manage the next state.


I only need to describe the Q side, "state" and it's update procedure.
Synthesis can work out the D side if I let it.

Here's how I pack lots of registers into a single process:
http://mysite.verizon.net/miketreseler/stack.vhd
http://mysite.verizon.net/miketreseler/stack.pdf

Good luck.

-- Mike Treseler
Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 02:27 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.