VHDL - "Чистый привод постоянно движется"

Я пытаюсь изучить VHDL и в качестве упражнения я пытаюсь создать очень простой последовательный порт, который использует сигнализацию в стиле RS-232 (формат 8N1).

Вот код для обоих VHDL-файлов в небольшом проекте...

"glue.vhd"... (модуль верхнего уровня)

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use ieee.std_logic_unsigned.all;
library MACHXO2;
use MACHXO2.components.all;

entity Glue is
    port(
        tx : out std_logic := '1' --idle high
        );
end entity Glue;

architecture behavioural of Glue is
    SIGNAL clk  : STD_LOGIC;
    signal divider : std_logic_vector(23 downto 0);

--internal oscillator
    COMPONENT OSCH
      GENERIC(
            NOM_FREQ: string
            );
      PORT( 
            STDBY    : IN  STD_LOGIC;
            OSC      : OUT STD_LOGIC;
            SEDSTDBY : OUT STD_LOGIC);
    END COMPONENT;
begin
--internal oscillator
   OSCInst0: OSCH
      GENERIC MAP (NOM_FREQ  => "3.69")
      PORT MAP (STDBY => '0', OSC => clk, SEDSTDBY => OPEN);

    ser : entity SerialTX
    port map (baud_clk => divider(5),
            byte_to_transmit => "00101001",
            transmit_now => divider(16),
            busy => OPEN,
            serial_out => tx);

    clocker : process (clk)
    begin
        IF(clk'event and clk='1') then
            divider <= divider + 1;
        END IF;
    end process clocker;

end architecture behavioural;

SerialTX.vhd... (вызывается glue.vhd)

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity SerialTX is
    port (
        baud_clk         : in  std_logic;
        byte_to_transmit : in  std_ulogic_vector(7 downto 0); --the byte that we want to transmit
        transmit_now     : in  std_logic;                    --a rising edge causes the byte to be sent out
        busy             : out std_logic;                    --wait for this to go low before transmiting more data
        serial_out       : out std_logic                     --the RS232 serial signal
        );
end SerialTX;

architecture behavioural of SerialTX is
    signal bit_buf : unsigned(9 downto 0); --(STOP bit) & (8 data bits) & (START bit)
    signal internal_busy : std_logic := '0';
begin
    busy <= internal_busy;  

    initialise_transmit : process(transmit_now, internal_busy) is
    begin
        if(transmit_now'event and (transmit_now = '1')) then
            if((internal_busy = '0')) then
                internal_busy <= '1'; --causes the "transmit_bits" process below to begin shifting out bits
                bit_buf <= unsigned('1' & byte_to_transmit & '0'); --latch in the byte to our internal copy
            end if;
        end if;
    end process initialise_transmit;    

    transmit_bits : process(internal_busy, baud_clk) is
        variable bit_counter : integer range 0 to 10 := 0;
    begin
        if(baud_clk'event and (baud_clk = '1')) then
            if(internal_busy = '1') then
                serial_out <= bit_buf(0);
                bit_buf <= bit_buf srl 1;
                bit_counter := bit_counter + 1;

                if(bit_counter = 10) then
                    internal_busy <= '0'; --finished sending
                    bit_counter := 0;
                end if;
            end if;
        end if;            -- ------------------------------ERROR HERE
    end process transmit_bits;
end behavioural;

Код VHDL, который использует этот модуль, предоставляет ему тактовую частоту в бодах, 8 бит данных для отправки и передний фронт, чтобы сигнализировать, что передача должна начаться.

Чтобы проверить это, я подключу логический анализатор к выводу "tx", чтобы увидеть выходной сигнал последовательного сигнала. Я жестко закодировал байт как букву "А" (000101001), чтобы я мог доказать, что основная концепция работает.

Проблема... Цепочка инструментов (Lattice Diamond 3.9) не может синтезировать этот дизайн в его нынешнем виде, так что, очевидно, я допустил ошибку в структуре объектов.

По отдельности оба файла не имеют синтаксических предупреждений или ошибок вообще. В проекте нет других VHDL-файлов, кроме встроенных зависимостей, предоставляемых библиотеками Lattice и IEEE.

Результат запуска процесса "Механизм синтеза решетки" следующий:

Analyzing Verilog file C:/lscc/diamond/3.9_x64/ispfpga/userware/NT/SYNTHESIS_HEADERS/machxo2.v. VERI-1482
Compile design.
Compile Design Begin
INFO - The default VHDL library search path is now "C:/Users/XXXXXXXXXXXX.XXXXXXXXXXXX/Documents/Lattice/impl1". VHDL-1504
Analyzing VHDL file c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/serialtx.vhd. VHDL-1481
INFO - c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/serialtx.vhd(5): analyzing entity serialtx. VHDL-1012
INFO - c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/serialtx.vhd(15): analyzing architecture behavioural. VHDL-1010
unit Glue is not yet analyzed. VHDL-1485
Analyzing VHDL file c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/glue.vhd. VHDL-1481
INFO - c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/glue.vhd(8): analyzing entity glue. VHDL-1012
INFO - c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/glue.vhd(14): analyzing architecture behavioural. VHDL-1010
unit Glue is not yet analyzed. VHDL-1485
WARNING - Net pwr has following drivers :
unit Glue is not yet analyzed. VHDL-1485
c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/glue.vhd(8): executing Glue(behavioural)

WARNING - c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/glue.vhd(12): replacing existing netlist Glue(behavioural). VHDL-1205
Top module name (VHDL): Glue
Last elaborated design is Glue(behavioural)
Loading NGL library 'C:/lscc/diamond/3.9_x64/ispfpga/xo2c00a/data/xo2alib.ngl'...
Loading NGL library 'C:/lscc/diamond/3.9_x64/ispfpga/xo2c00/data/xo2clib.ngl'...
Loading NGL library 'C:/lscc/diamond/3.9_x64/ispfpga/mg5g00/data/mg5glib.ngl'...
Loading NGL library 'C:/lscc/diamond/3.9_x64/ispfpga/or5g00/data/orc5glib.ngl'...
Loading device for application map from file 'xo2c1200.nph' in environment: C:/lscc/diamond/3.9_x64/ispfpga.
Package Status:                     Final          Version 1.42.
Top-level module name = Glue.
WARNING - Initial value found on net tx will be ignored due to unrecognized driver type
WARNING - Net pwr has following drivers :
     instance i2

     instance internal_busy_28



ERROR - c:/users/XXXXXXXXXXXX.XXXXXXXXXXXX/documents/lattice/serialtx.vhd(45): net pwr is constantly driven from multiple places at instance internal_busy_28, on port q. VDB-1000
Done: error code 2

"net pwr постоянно запускается из нескольких мест" в строке 45 (обозначено комментарием "ОШИБКА ЗДЕСЬ" в листинге кода).

Я не понимаю, что здесь не так, на мой неопытный взгляд, похоже, что сигнал internal_busy низкий, пока не достигнет высокого уровня после того, как получит нарастающий фронт на trans_now.

Что я делаю неправильно?

1 ответ

Решение

Сообщение об ошибке не очень полезно, но, глядя на файл SerialTx.vhd, вы управляете сигналом internal_busy из двух разных процессов. Сигнал может передаваться только в одном процессе, чтобы дизайн был пригоден для синтеза.

Еще одна ошибка, которую я вижу здесь: tx : out std_logic := '1' --idle high, Это не делает то, что вы думаете, что делает. Вы можете установить начальное значение для сигнала, где находится его драйвер, но установка такого значения в какой-то другой точке иерархии ничего не делает. Если вам нужен сигнал для простоя в определенном состоянии, вы должны написать код, который переводит сигнал в это состояние, когда он простаивает.

Также лучше заменить условия обнаружения часов, такие как baud_clk'event and (baud_clk = '1') с rising_edge(baud_clk),

Другие вопросы по тегам