cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
462 Views
Registered: ‎11-10-2020

How can I give an output an initial value?

Jump to solution

I have the entity below which converts a 4bit input (i_Data) into 2 2bit 'symbols' (r_Sym1, r_Sym2) and then outputs them both once per second. For example if i_Data is "1101", then the output o_Symbol would be "11" for half a second, then change to "01" for half a second, and then repeat. Its controlled by a 2Hz clock enable signal, so the output changes on each pulse of this signal (every 0.5 seconds).

When I simulate this, it works as it should, but doesn't start to output until the first clock enable signal at 0.5 sec. I want it to start outputting straight away. So at the moment, o_Symbol is U for half a second, then "11" for half a second, then "01" etc etc.

I need to get rid of this half second of U, so that the output is "11" at the start, and changes to "01" at 0.5 sec. 

This means that the initial value of o_Symbol should be i_Data(3 downto 2). How can I set this? It seems to give me errors with everything I try.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity T29_M2_SymbolConv is
    generic (g_maxCount: natural);   -- maxCount = 2
    port (i_Data: in std_logic_vector(3 downto 0) ;
        i_CE2Hz, i_clk: in std_logic;
        o_Symbol: out std_logic_vector(1 downto 0));
end T29_M2_SymbolConv; 

architecture behavioral of T29_M2_SymbolConv is
    signal r_count: natural range 0 to g_maxCount := 0;
    signal r_Sym1: std_logic_vector(1 downto 0);
    signal r_Sym2: std_logic_vector(1 downto 0);
begin
    -- Internal counter process
    countProc : process( i_clk )
    begin
        if rising_edge(i_clk) then -- sync on rising edge
            if r_count < g_maxCount - 1 then
                r_count <= r_count + 1;  
            else
                r_count <= 0;     
            end if ;
        end if;
    end process ;

    symbolConv : process( i_CE2Hz )
    begin
        r_Sym1 <= i_Data(3 downto 2);
        r_Sym2 <= i_Data(1 downto 0);
        if i_CE2Hz = '1' then
            if r_count = 0 then
                o_Symbol <= r_Sym1;
            else
                o_Symbol <= r_Sym2;
            end if;
        end if;
    end process ;
end architecture;

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Visitor
Visitor
360 Views
Registered: ‎11-10-2020

After spending all day playing around with different ideas, I found a solution:

I adjusted symbolConv process and added an else statement that outputs the first symbol when the clock enable signal is low (i.e. straight away). I also added a variable to ensure that this else statement only runs once, at the start of the simulation, otherwise it would output the first symbol every time CE is low, instead of just the first one.

symbolConv : process (i_CE2Hz)
        variable tmp: integer range 0 to 1 := 0;
    begin
        r_Sym1 <= i_Data(3 downto 2);
        r_Sym2 <= i_Data(1 downto 0);
        if i_CE2Hz = '1' then
            if r_count = 0 then
                o_Symbol <= r_Sym2;
            else
                o_Symbol <= r_Sym1;
            end if;
        elsif i_CE2Hz = '0' and tmp = 0 then
            o_symbol <= r_Sym1;
            tmp := tmp + 1;
        end if;
    end process ;

View solution in original post

0 Kudos
9 Replies
Highlighted
Teacher
Teacher
430 Views
Registered: ‎07-09-2009
FPGAs are initalised at start up when they are configured.

to set what this start up value is , its done in the signal definition,

e.g.

signal r_Sym1: std_logic_vector(1 downto 0) := B"10";
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Teacher
Teacher
429 Views
Registered: ‎07-09-2009
A few other things,
you are missing signals in the sensitivity list for
symbolConv : process( i_CE2Hz )

Your also going to form a latch
is that intended ?
the tools are real bad at working with latches, and we normaly code against latches.
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Visitor
Visitor
393 Views
Registered: ‎11-10-2020

Assigning a start up value didn't fix it. I think my problem is that the initial value has to be taken from the input, instead of being a number I can define (since it will change depending on the input). The output only updates when CE2Hz goes high, so I'm wondering if its possible to 'artificially' pulse i_CE2Hz straight away, just once? I can't give it an initial value since it is supplied by another entity which controls when it pulses, so I don't really know how I would do this. 

What else would I need in the sensitivity list, and I'm not sure what you mean about the latch, could you explain?

0 Kudos
Highlighted
Teacher
Teacher
381 Views
Registered: ‎07-09-2009
Do you need the latch ?
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Visitor
Visitor
378 Views
Registered: ‎11-10-2020
I don't think so, I wasn't aware I'd put it in. Which part of the code is it?
0 Kudos
Highlighted
Observer
Observer
354 Views
Registered: ‎11-21-2020

 

Something like this?

I didn't simulated/synthesized it.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity T29_M2_SymbolConv is
    port (i_Data: in std_logic_vector(3 downto 0) ;
        i_CE2Hz, i_clk: in std_logic;
        o_Symbol: out std_logic_vector(1 downto 0));
end T29_M2_SymbolConv; 

architecture behavioral of T29_M2_SymbolConv is
    signal reset : std_logic := '1';
    signal ping_pong : std_logic;
begin
    process( i_clk )
    begin
        if rising_edge(i_clk) then
            if (reset = '1') then
                reset <= '0';
                ping_pong <= '1';
                o_Symbol <= i_Data(3 downto 2);
            else if (i_CE2Hz = '1') then
                 ping_pong <= NOT ping_pong;
                 if (ping_pong = '0')
                 then o_Symbol <= i_Data(3 downto 2);
                 else o_Symbol <= i_Data(1 downto 0);
                 end if;
            end if;
        end if;
    end process ;
end architecture;

 

0 Kudos
Highlighted
Visitor
Visitor
361 Views
Registered: ‎11-10-2020

After spending all day playing around with different ideas, I found a solution:

I adjusted symbolConv process and added an else statement that outputs the first symbol when the clock enable signal is low (i.e. straight away). I also added a variable to ensure that this else statement only runs once, at the start of the simulation, otherwise it would output the first symbol every time CE is low, instead of just the first one.

symbolConv : process (i_CE2Hz)
        variable tmp: integer range 0 to 1 := 0;
    begin
        r_Sym1 <= i_Data(3 downto 2);
        r_Sym2 <= i_Data(1 downto 0);
        if i_CE2Hz = '1' then
            if r_count = 0 then
                o_Symbol <= r_Sym2;
            else
                o_Symbol <= r_Sym1;
            end if;
        elsif i_CE2Hz = '0' and tmp = 0 then
            o_symbol <= r_Sym1;
            tmp := tmp + 1;
        end if;
    end process ;

View solution in original post

0 Kudos
Highlighted
Scholar
Scholar
180 Views
Registered: ‎08-01-2012

This is not going to work.

This code creates a latch on hardware. WHen i_CE2Hz is '0' and tmp is 1, the o_symbol output has to remember its value. This means it creates a latch, and can cause all sorts of timing issues.

You are also missing several signals from the symbolConv sensitivity list (like @drjohnsmith ) already pointed out, that means the simulation will behave differently from the hardware.

You cannot initilise a signal to be another signal. THat signal would also have a fixed initial value. If you want to do this you will need to use generics, or have some form of input to set your signal (hopefully using a clock) to be another signal.

I worry your design is going to fail in ways that do not present themselves immediately.

Highlighted
Teacher
Teacher
134 Views
Registered: ‎07-09-2009

Have you looked at the warnings you are getting ?

    the tools have been warning you about latches and missing signals in sensitivity list.

A latch is formed when a combinational process has an output that is not defined in a particular case.

Have a ready through here

https://www.doulos.com/knowhow/vhdl/synthesizing-latches/

 

Bottom line , as has been said many times before,

    remember what you are doing is describing hardware,

       if in doubt, try to draw what hardware you want .

 

 

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos