# VHDL code for beacon

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?

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).

--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:

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).

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.

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;