1
\$\begingroup\$

I'm trying to make a block in VHDL that will send to the output sequece of ones and zeros (signal code) but I can't make any progress. Code is compiled, but in simulation the output doesn't react as I expect, it keeps sending zeros. The following is my code:

--beacon
library ieee;
use ieee.std_logic_1164.all;

entity beacon is
        port
        (       START : in std_logic;
                CLK : in std_logic;
                Q : out bit
        );
end;

architecture dataflow of beacon is
signal code : bit_vector(0 downto 45);
signal index : integer;
begin
        code <= "0111010111000101011100011101110001011101110100";
        index <= 46;
        st : process(START)
        begin
                if rising_edge(START) then
                        index <= 0;
                end if;
        end process;

        b : process(CLK)
        begin
                if rising_edge(CLK) then
                        if(index < 46) then
                                Q <= code(index);
                                index <= index + 1;
                        end if;
                end if;

        end process;
end;

I'm new to VHDL. Could anybody give me some advice on what's wrong in my code?

\$\endgroup\$
2
\$\begingroup\$

There are two things immediately obviously wrong. First the declaration of code has a null range ("0 downto 45" should be "0 to 45") second, you have two processes assigning values to the same signal (index) which isn't a resolved type. Each process containing a signal assignment to index will have a driver.

The first is an analysis time error, you should have been notified the string length doesn't match the range of code (which is a null range with downto). The second is a simulation error ("It is an error if, after the elaboration of a description, a signal has multiple sources and it is not a resolved signal."). Either should have been sufficient to prevent your simulation from running, which speaks to the tool you are using.

The way to fix the second problem might be to consolidate the two processes, using START as a synchronous enable, logically OR'd with index /= 0. You appear to want START to mark the first output bit in any event. When index is 45 next index should be zero, requiring START to kick it off (again).

I made the following changes to your code (beacon.vhdl):

--signal code : bit_vector(0 downto 45);
signal code : bit_vector(0 to 45);
--signal index : integer;
signal index : integer := 0;

(Note the index could have as easily had a range assigned: signal index : integer range 0 to 45; (The required thing here is the left value set to 0), which either signal declaration form accomplishes.)

--        index <= 46;
        -- st : process(START)
        -- begin
        --         if rising_edge(START) then
        --                 index <= 0;
        --         end if;
        -- end process;
        -- 
        -- b : process(CLK)
        -- begin
        --         if rising_edge(CLK) then
        --                 if(index < 46) then
        --                         Q <= code(index);
        --                         index <= index + 1;
        --                 end if;
        --         end if;
        -- 
        -- end process;
        b : process(CLK)
        begin
            if rising_edge(CLK) then
                if index /= 0 or START = '1' then
                    Q <= code(index);
                    if index = 45 then
                        index <= 0;
                    else
                        index <= index + 1;
                    end if;
                end if;
            end if;

        end process;

(Which consolidates the two processes)

This gives:

test simulation

When used with the testbench:

library ieee;
use ieee.std_logic_1164.all;

entity test is
end entity;

architecture foo of test is
    signal START:   std_logic := '0';
    signal CLK:     std_logic := '1';
    signal Q:       Bit;
begin
DUT:   entity work.beacon
    port map (START, CLK, Q);
CLOCK:
    process 
    begin
        wait for 20 ns;
        CLK <= not CLK;
        if (now >= 2 us) then
            wait;
        end if;
    end process;
STIMULUS:
    process
    begin
        wait for 45 ns;
        START <= '1';
        wait for 40 ns;
        START <= '0';
        wait; 
    end process;

end architecture;

This was done on a Macbook using ghdl and gtkwave.

%% ghdl -a beacon.vhdl # modified as noted above, test bench test appended    
%% ghdl -e test        # not needed in mcode versions of ghdl    
%% ghdl -r test --wave=test.ghw
%% gtkwave test.ghw    # after setting up, write your save file

The test bench limits the length of the simulation by stopping the clock (see evaluation of the expression containing now).

\$\endgroup\$
0
\$\begingroup\$

I think you should set your default values rather this way: https://stackoverflow.com/a/14527926/663068. I belive your code variable is simply set to zeros and command:

code <= "0111010111000101011100011101110001011101110100";

is not beeing executed properly.

\$\endgroup\$
0
\$\begingroup\$

A more generic way of doing things, allowing you to easily change the length of code and not have to change anything else.

In the process, we remove your bug of defining the range of code as 0 downto 45 which is a null range...

architecture dataflow of beacon is
constant code : bit_vector := "0111010111000101011100011101110001011101110100";
signal index : integer range 0 to code'high + 1;
begin
        index <= code'high;
        st : process(START)
        begin
                if rising_edge(START) then
                        index <= 0;
                end if;
        end process;

        b : process(CLK)
        begin
                if rising_edge(CLK) then
                        if(index < code'high+1) then
                                Q <= code(index);
                                index <= index + 1;
                        end if;
                end if;

        end process;
end;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.