When are concurrent assignments updated?

Discussion in 'VHDL' started by Svenn Are Bjerkem, Aug 12, 2008.

  1. Hi,

    tried to search for answer on something I don't quite understand, but
    found little. Maybe I don't know the right keywords to search for:

    In an SPI I have an internal data register called data_int which looks
    like this:

    process(clk,reset)
    begin
    if reset = '1' then
    ....
    elsif rising_edge(clk) then
    .....
    data_int <= data_int(8 downto 0) & SDATA
    .....
    end if;
    end process;
    DATA <= data_int;

    DATA and SDATA are ports on the entity and both DATA and data_int are
    std_logic_vector(8 downto 0) and SDATA is serial data from slave SPI
    of std_logic type.

    When simulating with modelsim, I see that data_int is updated on the
    rising edge of clk. data, on the other hand, is updated on the
    following falling edge of clk. This I don't understand. I also tried
    data <= data_int after 1 ns;
    but that just delayed the update of data 1 ns after the falling edge
    of clk. My code doesn't have any timing resolution statements, and I
    don't know if modelsim has something by default, and I haven't found
    anything about this half-cycle delay in any of the books I have.

    Anybody have a pointer to what I am missing here?
     
    Svenn Are Bjerkem, Aug 12, 2008
    #1
    1. Advertisements

  2. Yeah, I wanted to avoid that, as the code is not finished. There are
    things not working according to spec, and things that may be
    completely wrong, it is the first step on a journey, but I have this
    simulation problem that I do not get around, so here you go. Help me,
    don't use it against me :)

    --
    Svenn


    library ieee;
    use ieee.std_logic_1164.all;

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

    entity spi_ad7273 is

    port (
    -- external interface
    SDATA : in std_logic;
    SCLK : out std_logic;
    CS_N : out std_logic;
    -- internal interface
    CLK : in std_logic;
    RESET : in std_logic;
    DATA : out std_logic_vector(9 downto 0);
    DATA_REQ : in std_logic;
    DATA_RDY : out std_logic
    );

    end spi_ad7273;

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

    architecture rtl of spi_ad7273 is
    type sm_t is (spi_idle, spi_start, spi_transfer, spi_stop); --
    state machine states
    signal cur_state : sm_t; -- Current state
    signal data_int : std_logic_vector(9 downto 0);
    signal data_rdy_int : std_logic := '0';
    signal cs_n_int : std_logic := '1';
    signal sclk_en : std_logic;
    begin -- rtl
    p_ad7273_spi : process(RESET, CLK)
    variable bit_count : integer := 0; -- counts shifted bits
    begin
    if (RESET = '1') then
    data_int <= (others => '0');
    cur_state <= spi_idle;
    data_rdy_int <= '0';
    bit_count := 0;
    elsif CLK'event and CLK = '1' then
    data_int <= data_int;
    cur_state <= spi_idle;
    case cur_state is
    when spi_idle =>
    if DATA_REQ = '1' then
    sclk_en <= '1';
    bit_count := 9;
    cs_n_int <= '0';
    cur_state <= spi_transfer;
    end if;
    when spi_transfer =>
    data_rdy_int <= '0';
    data_int <= data_int(8 downto 0) & SDATA;
    if bit_count = 0 then
    cur_state <= spi_stop;
    else
    cur_state <= spi_transfer;
    end if;
    bit_count := bit_count - 1;
    when spi_stop =>
    data_rdy_int <= '1';
    cs_n_int <= '1';
    sclk_en <= '0';
    cur_state <= spi_idle;
    when others => null;
    end case;
    end if;
    DATA <= data_int after 1 ns;
    DATA_RDY <= data_rdy_int;
    CS_N <= cs_n_int;
    SCLK <= CLK and sclk_en;
    end process;
    end rtl;
    -------------------------------------------------------------------------------


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

    library ieee;
    use ieee.std_logic_1164.all;

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

    entity spi_ad7273_tb is

    end spi_ad7273_tb;

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

    architecture test of spi_ad7273_tb is

    component spi_ad7273
    port (
    SDATA : in std_logic;
    SCLK : out std_logic;
    CS_N : out std_logic;
    CLK : in std_logic;
    RESET : in std_logic;
    DATA : out std_logic_vector(9 downto 0);
    DATA_REQ : in std_logic;
    DATA_RDY : out std_logic);
    end component;
    component ad7273
    port (
    sdata : out std_logic;
    sclk : in std_logic;
    cs_n : in std_logic);
    end component;

    -- component ports
    signal SDATA : std_logic;
    signal SCLK : std_logic;
    signal CS_N : std_logic;
    signal CLK : std_logic := '0';
    signal RESET : std_logic;
    signal DATA : std_logic_vector(9 downto 0);
    signal DATA_REQ : std_logic;
    signal DATA_RDY : std_logic;

    -- clock
    --signal Clk : std_logic := '1';

    begin -- test

    -- component instantiation
    DUT: spi_ad7273
    port map (
    SDATA => SDATA,
    SCLK => SCLK,
    CS_N => CS_N,
    CLK => CLK,
    RESET => RESET,
    DATA => DATA,
    DATA_REQ => DATA_REQ,
    DATA_RDY => DATA_RDY);
    driver: ad7273
    port map (
    sdata => sdata,
    sclk => sclk,
    cs_n => cs_n);

    -- clock generation
    Clk <= not Clk after 10 ns;

    -- waveform generation
    WaveGen_Proc: process
    begin
    -- insert signal assignments here
    data_req <= '0';
    reset <= '0';
    wait for 50 ns;
    reset <= '1';
    wait for 50 ns;
    reset <= '0';
    wait for 55 ns;
    data_req <= '1';
    wait for 500 ns;
    data_req <= '0';
    wait;
    end process WaveGen_Proc;



    end test;

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

    library ieee;
    use ieee.std_logic_1164.all;

    entity ad7273 is
    port(
    sdata : out std_logic;
    sclk : in std_logic;
    cs_n : in std_logic
    );
    end entity;
    architecture rtl of ad7273 is
    signal sdata_int : std_logic := 'Z';
    signal sdata_reg : std_logic_vector(9 downto 0) := "1010101010";
    begin
    process(sclk,cs_n)
    variable i : integer := 0;
    begin
    if sclk'event and sclk = '0' then
    if cs_n = '0' then
    sdata_int <= not sdata_reg(i mod 10);
    i := i + 1;
    else
    i := 0;
    sdata_int <= 'Z';
    end if;
    end if;
    end process;
    sdata <= sdata_int;
    end rtl;
     
    Svenn Are Bjerkem, Aug 13, 2008
    #2
    1. Advertisements

  3. The entity that I will use later is the spi_ad7273. the entity ad7273
    is a model of the AD-converter that I am talking to and will be used
    only for testing spi_ad7273.
     
    Svenn Are Bjerkem, Aug 14, 2008
    #3
  4. I lick my wounds. Moving the assignments out of the process solved the
    problem, as expected, and I don't really know why they were in there
    at all. Must have been sleeping while typing and later got so code
    blind that I didn't see it. Well it is always good to have somebody
    review the code, and then the real code and not some here-is-what-I-
    think-I-have-done snippet. Thanks a lot to you guys.
     
    Svenn Are Bjerkem, Aug 14, 2008
    #4
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.