VHDL(Xilinx工具链)正因“数组修整” [英] VHDL (Xilinx toolchain) I'm being scuppered by "array trimming"

查看:150
本文介绍了VHDL(Xilinx工具链)正因“数组修整”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个两文件的VHDL项目,我遇到了初学者的困难。



它占用系统时钟并使用30位时钟分频器(其中我仅使用少量非连续位)来驱动原始串行端口模块(仅传出TX)模块,以定期吐出8位字符。



似乎在合成过程中,优化器删除了许多基本信号,这是我所没有想到的。



顶部级别文件 Glue.vhd ...

 库IEEE; 
使用IEEE.std_logic_1164.all;
使用IEEE.numeric_std.all;
使用ieee.std_logic_unsigned.all;

实体胶是
端口(
clk:in std_logic;
tx:out std_logic;
LED:out std_logic_vector(1至0)
);
最终实体胶水; Glue的

架构行为是
信号分配器:unsigned(29 downto 0);
开始
LED(1)< =‘0’;

ser_tx:实体SerialTX
端口映射(
baud_clk =>除法器(12),
byte_to_transmit => std_ulogic_vector(除法器(29降到22)),
poke =>分隔器(20),
busy => LED(0),
serial_out => tx
);

clocker:process(clk)
开始
IF(rising_edge(clk))然后
除法器< =除法器+ 1;
END IF;
结束进程时钟;
结束架构行为;

SerialTX.vhd

 库IEEE; 
使用IEEE.std_logic_1164.all;
使用IEEE.numeric_std.all;

实体SerialTX是
端口(
baud_clk:在std_logic中;
byte_to_transmit:在std_ulogic_vector(7至0);-我们要传输的字节
poke:in std_logic;-上升沿导致字节发送出去
busy:out std_logic;-等待此消息变低之后再传输更多数据
serial_out:out std_logic- -RS232串行信号
);
结尾SerialTX; SerialTX的

架构行为是
signal bit_buf:unsigned(9 downto 0); -(停止位)& (8个数据位)& (START位)
信号internal_busy:std_logic;
共享变量bit_counter:0到10的整数范围;
开始
busy< = internal_busy;

busy_handler:进程(poke)为
开始
if(rising_edge(poke))然后
internal_busy< =‘1’;
结尾,如果;
if(bit_counter = 0)然后
internal_busy< =‘0’;
结尾,如果;
结束进程busy_handler;

do_transmit:进程(baud_clk)为
开始
if(rising_edge(baud_clk))然后
if((internal_busy ='1')and(bit_counter = 0 ))然后
bit_counter:= 10;
bit_buf< = unsigned('1'& byte_to_transmit&'0');
结尾,如果;

serial_out< = bit_buf(0);
bit_buf< = bit_buf srl 1;
bit_counter:= bit_counter-1;
结尾,如果;
结束进程do_transmit;
结束行为;

综合过程中的警告(请注意,没有错误)如下遵循...

 警告:Xst:647-输入< byte_to_transmit>从未使用过。如果该端口属于顶层块或属于子块,并且该子块的层次结构得到保留,则将保留该端口并使其保持未连接状态。 
警告:Xst:1710-FF /锁< bit_buf_9> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修整,FF /锁存器< bit_buf_8> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修剪,FF /锁存器< bit_buf_7> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修整,FF /锁存器< bit_buf_6> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修整,FF /锁存器< bit_buf_5> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修整,FF /锁存器< bit_buf_4> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修剪,FF /锁存器< bit_buf_3> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修整,FF /锁存器< bit_buf_2> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修整,FF /锁存器< bit_buf_1> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /锁存器修整,FF /锁存器< bit_buf_0> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:1895-由于其他FF /闩锁修整,FF /闩锁< serial_out> (没有初始值)在块< ser_tx>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:2404-FF /闩锁< bit_buf< 9:0>> (没有初始值)在块< SerialTX>中具有恒定值0。
警告:Xst:1710-FF /闩锁< serial_out> (没有初始值)在块< SerialTX>中具有恒定值0。在优化过程中将修整该FF /锁存器。
警告:Xst:2677-节点< divider_21>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_22>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_23>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_24>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_25>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_26>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_27>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_28>在框< Glue>中未连接顺序类型的 Glue。
警告:Xst:2677-节点< divider_29>在框< Glue>中未连接顺序类型的 Glue。
警告:路由:455-CLK网络:divider< 20>由于0个CLK引脚和1个NON_CLK引脚无法使用CLK模板进行路由,因此可能存在过多的偏斜。
警告:路由:455-CLK网络:分频器< 12>可能有过多的偏斜,因为0个CLK引脚和1个NON_CLK引脚无法使用CLK模板进行布线。

我已经跟踪了源代码中的连接,但找不到我所犯的错误制造。我感觉到我缺少一些未在作业中涵盖的边缘/角落情况。



标记为(无初始值)的项目尝试通过给默认值无济于事来进行纠正。标记为块中未连接的那些令人困惑。



我该怎么做才能满足合成器的要求?

解决方案

您可以模拟您的设计,因为它处于复杂性的边缘,比猜测为什么将其合成并加载到FPGA中为什么不起作用要容易得多。也可以将其设置为



byte_to_transmit值05的特写:



< a href = https://i.stack.imgur.com/9nO3U.png rel = nofollow noreferrer>



您可能会注意到,软件包std_logic_1164中未提供srl,并且已替换为std_ulogic_vector,std_logic_vector成为了-2008中的子类型。



p 被过滤到baud_clk域中并生成单个时钟周期事件,集合 internal_busy 为'1',随后在 bit_buf 中再次检测到空闲模式时,随后将其设置为'0'。



注意 busy 为10个时钟(起始位,8个数据位和停止位)为'1',而第11个触发器为serial_out已被删除。



这是使用



请注意,internal_busy信号用于确定何时发生繁忙的后沿(在发送或发送时区分bit_buf中的空闲模式或



通过修改胶水来缩短戳信号,以证明戳的宽度(发送)可以是任意的:

  Glue的体系结构行为是
信号分配器:unsigned(29 downto 0):=(others =>'0'); -init val
signal poke:std_logic:='0'; -添加
开始
LED(1)< =‘0’;

戳< =分频器(17),在10 us之后为 0; -添加
ser_tx:
实体工作.SerialTX-添加工作前缀以使所选名称
端口映射(
baud_clk =>分隔符(12),
-byte_to_transmit => std_ulogic_vector(divider(29 downto 22)),
byte_to_transmit => std_logic_vector(divider(25 downto 18)),-sim
poke => poke,-WAS除法器(20),用于仿真
busy => LED(0),
serial_out => tx
);

(不,表示新信号戳的单发信号的复杂波形不符合合成条件。)


I've got a two-file VHDL project that I'm having beginner's difficulties with.

It takes the system clock and use a 30-bit clock divider (of which I'm only using a small number of non-consecutive bits) to drive a primitive serial port module (outgoing TX only) module to spit out 8 bit characters periodically.

It seems that during the synthesis process, many of the essential signals are being removed by the optimizer, which I didn't expect.

The top level file "Glue.vhd"...

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

entity Glue is
    port(
        clk : in std_logic;
        tx  : out std_logic;
        LED : out std_logic_vector(1 downto 0)
        );
end entity Glue;

architecture behavioural of Glue is
    signal divider : unsigned(29 downto 0);
begin
    LED(1) <= '0';

    ser_tx : entity SerialTX
    port map (
            baud_clk => divider(12),
            byte_to_transmit => std_ulogic_vector(divider(29 downto 22)),
            poke => divider(20),
            busy => LED(0),
            serial_out => tx
            );

    clocker : process(clk)
    begin
        IF(rising_edge(clk)) then
            divider <= divider + 1;
        END IF;
    end process clocker;
end architecture behavioural;

SerialTX.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
        poke             : 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;
    shared variable bit_counter   : integer range 0 to 10;
begin
    busy <= internal_busy;

    busy_handler : process(poke) is
    begin
        if(rising_edge(poke)) then
            internal_busy <= '1';
        end if;
        if(bit_counter = 0) then
            internal_busy <= '0';
        end if;
    end process busy_handler;

    do_transmit : process(baud_clk) is
    begin
        if(rising_edge(baud_clk)) then 
            if((internal_busy = '1') and (bit_counter = 0)) then
                bit_counter := 10;
                bit_buf <= unsigned('1' & byte_to_transmit & '0');
            end if;

            serial_out <= bit_buf(0);
            bit_buf <= bit_buf srl 1;
            bit_counter := bit_counter - 1;
        end if;
    end process do_transmit;
end behavioural;

The warnings (no errors mind you) from the synthesis process are as follows...

WARNING:Xst:647 - Input <byte_to_transmit> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
WARNING:Xst:1710 - FF/Latch <bit_buf_9> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_8> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_7> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_6> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_5> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_4> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_3> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_2> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_1> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <bit_buf_0> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <serial_out> (without init value) has a constant value of 0 in block <ser_tx>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:2404 -  FFs/Latches <bit_buf<9:0>> (without init value) have a constant value of 0 in block <SerialTX>.
WARNING:Xst:1710 - FF/Latch <serial_out> (without init value) has a constant value of 0 in block <SerialTX>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:2677 - Node <divider_21> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_22> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_23> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_24> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_25> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_26> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_27> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_28> of sequential type is unconnected in block <Glue>.
WARNING:Xst:2677 - Node <divider_29> of sequential type is unconnected in block <Glue>.
WARNING:Route:455 - CLK Net:divider<20> may have excessive skew because     0 CLK pins and 1 NON_CLK pins failed to route using a CLK template.
WARNING:Route:455 - CLK Net:divider<12> may have excessive skew because     0 CLK pins and 1 NON_CLK pins failed to route using a CLK template.

I've traced through the connections in the source code and I cannot find the mistakes that I'm making. I get the feeling that I'm missing some edge/corner cases that I've not covered in the assignments.

The items marked "(without init value)" I have tried to rectify by giving them default values to no avail. The ones marked as "unconnected in block " are bewildering.

What must I do to satisfy the synthesizer?

解决方案

You can simulate your design, it's on the edge of complexity where it would be easier than guessing why it doesn't work when synthesized and loaded in an FPGA. It can also be made simpler.

It's possible to get rid of bit_counter because you have a 10 bit bit_buf shift register.

The way this would work, is that you set a default pattern that is recognized as 'empty', and that pattern is constructed as a result of shifting bit_buf out.

The pattern doesn't occur other than as an artifact of shifting out with a 'left' shift in of '0'. The shift register shifts '0's in and stops when the stop bit is in the right most position ("0000000001"). The '1' in the right had position maintains the transmit idle mark.

The idea of the idle pattern comes from your use of srl which left fills with '0's, noticed while debugging your original design. The amount of incremental changes while 'learning' why you designed this the way you did became prohibitive. It lead to looking at first principles and describing an implementation based on yours from that.

To simulate your design to begin with there are changes to Glue including an initial value for divide so the increment works, and moving the divider tap-offs for poke and byte_to_transmit, to reduce the simulation time to the neighborhood of 40 ms for the following.

The instantiation of SerialTx uses a selected name, simulators don't include a use work.all; context item implicitly, as is sometimes provided in synthesis tools.

A mark up of your design with an added testbench, without bit_counter:

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_logic_vector(7 downto 0); -- before -2008
        poke:              in  std_logic;
        busy:              out std_logic;
        serial_out:        out std_logic
    );
end entity SerialTX;

architecture foo of SerialTX is
    -- signal bit_buf:         unsigned(9 downto 0);
    constant BB_IDLE:       std_logic_vector (9 downto 0) := "0000000001";
    signal bit_buf:         std_logic_vector (9 downto 0) := BB_IDLE;
    -- signal internal_busy:   std_logic;
    signal poke_reg:        std_logic_vector (0 to 2) := "000";
    signal start_tx:        std_logic;

    -- shared variable bit_counter:    integer range 0 to 10;
begin
    -- busy <= internal_busy;
poke_filt:
    process (baud_clk)  -- translate poke to baud_clk domain
    begin
        if rising_edge (baud_clk) then
            poke_reg <= poke & poke_reg (0 to 1);
        end if;
    end process;

    -- front edge of poke in baud_clk_domain:
    start_tx <= poke_reg(0) and poke_reg(1) and not poke_reg(2);

-- busy_handler:
--     process (poke) is
--     begin
--         if rising_edge (poke) then
--             internal_busy <= '1';
--         end if;
--         if bit_counter = 0 then
--             internal_busy <= '0';
--         end if;
--     end process busy_handler;

busy_handler:  
    process (baud_clk)
    begin
        if rising_edge (baud_clk) then
            if start_tx = '1' and bit_buf = BB_IDLE then
                busy <= '1';
            elsif bit_buf = BB_IDLE then
                busy <= '0';
            end if;
        end if;
    end process;

do_transmit:
    process (baud_clk)
    begin
        if rising_edge(baud_clk) then 
            if start_tx = '1'  and bit_buf = BB_IDLE then
                bit_buf <=  '1' & byte_to_transmit & '0';
            elsif bit_buf /= BB_IDLE then
                -- bit_buf <= bit_buf srl 1; 
                -- srl UNDEFINED in package std_logic_1164
                bit_buf <= '0' & bit_buf(9 downto 1); -- shift right one
            end if;                                   -- zero fill
        end if;
    end process;

-- do_transmit:
--     process (baud_clk)
--     begin
--         if rising_edge(baud_clk) then
--             if internal_busy = '1' and bit_counter = 0 then
--                 bit_counter := 10;
--                 bit_buf <= unsigned ('1' & byte_to_transmit & '0');
--             end if;
--             serial_out <= bit_buf(0);
--             bit_buf <= bit_buf srl 1;
--             bit_counter := bit_counter - 1;
--         end if;
--     end process do_transmit;

    serial_out <= bit_buf(0); -- ADDED, no 11th flip flop

end architecture;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- use ieee.std_logic_unsigned.all;

entity Glue is
    port (
        clk:  in  std_logic;
        tx:   out std_logic;
        LED:  out std_logic_vector(1 downto 0)
    );
end entity Glue;

architecture behavioural of Glue is
    signal divider:  unsigned(29 downto 0) := (others => '0'); -- init val
begin
    LED(1) <= '0';

ser_tx:  
    entity work.SerialTX  -- ADDED work prefix to make selected name
        port map (
            baud_clk => divider(12),
         -- byte_to_transmit => std_ulogic_vector(divider(29 downto 22)),
            byte_to_transmit => std_logic_vector(divider(25 downto 18)),
            poke => divider(17), -- WAS divider(20), for simulation
            busy => LED(0),
            serial_out => tx
        );
clocker:  
    process (clk)
    begin
        if rising_edge(clk) then
            divider <= divider + 1;
        end if;
    end process clocker;
end architecture behavioural;

library ieee;
use ieee.std_logic_1164.all;

entity glue_tb is
end entity;

architecture fum of glue_tb is
    signal clk:     std_logic := '0';
    signal tx:      std_logic;
    signal led:     std_logic_vector(1 downto 0);
begin
DUT:
    entity work.glue
        port map (
            clk => clk,
            tx => tx,
            led => led
        );
CLOCK:
    process
    begin
        wait for 10 ns;
        clk <= not clk;
        if now > 40 ms then
            wait;
        end if;
    end process;
end architecture;

Running for 40 ms gives:

A close up of byte_to_transmit value 05:

You could note srl is not provided in package std_logic_1164, and has been replaced as has the use of std_ulogic_vector, std_logic_vector became it's subtype in -2008.

poke is filtered into the baud_clk domain and generates an single clock period event the sets internal_busy to '1', which is subsequently set to '0' when the idle pattern is again detected in bit_buf.

Note busy is '1' for 10 clocks (start bit, 8 data bits, and stop bit) and the 11th flip flop for serial_out has been dropped.

This was simulated using ghdl, binaries can be downloaded here. The waveform displays are from gtkwave. Both are licensed under the GPL.

VHDL has a specific set of language constructs for inferring sequential logic - memories, registers and latches, part of a subset of the language useful in synthesis. A superset or subset of eligible VHDL is typically supported by a synthesis vendor who might also include restrictions based on their target platform silicon. Eligibility and supported constructs are found in synthesis vendor documentation. The VHDL language itself is defined in IEEE Std 1076-2008, although universal support is only found for the -1993 or -2002 revision.

One of the things you'll find is that shared variables have become protected types with access through methods, insuring exclusive access to shared resources and incidentally becoming ineligible for synthesis.

Am I right in thinking that your 3-bit poke_reg system means that the poke high pulse duration must be longer than 3 baud_clk edges in order to be correctly detected? Is it possible to make the poke signal edge-triggered? – Wossname 13 hours ago

scary_jeff 's method will work for poke (send) events shorter than or equal to three baud_clk intervals.

You don't use busy (internal_busy) in SerialTx and it only covers the interval of baud_clk periods (bauds) during actual transmission.

It's possible to create a busy signal that is safe (the xor of two flip flops) and works for the entire interval between the rising edge of poke (send) and the end of internal_busy:

architecture fum of SerialTX is
    constant BB_IDLE:       std_logic_vector (9 downto 0) := "0000000001";
    signal bit_buf:         std_logic_vector (9 downto 0) := BB_IDLE;
    signal poke_event:      std_logic := '0'; -- Added
    signal internal_busy:   std_logic := '0'; -- Re-Added
    signal poke_reg:        std_logic_vector (0 to 1) := "00";
    signal start_tx:        std_logic;
    signal end_event:       std_logic := '0'; -- Added
begin

    busy <= poke_event xor end_event;  -- ADDED, was FF output

pokeevent:
    process (poke)
    begin
        if rising_edge(poke) then
            poke_event <= not poke_event;
        end if;
    end process;
poke_edge:
    process (baud_clk)  -- translate poke to baud_clk domain
    begin
        if rising_edge (baud_clk) then
            poke_reg <= poke_event & poke_reg (0);
        end if;
    end process;

    -- front edge of poke in baud_clk_domain:
    start_tx <= poke_reg(0) xor poke_reg(1); -- CHANGED, when not equal

endevent:
    process (baud_clk)
    begin
        if rising_edge (baud_clk) then
            if internal_busy = '1' and bit_buf = BB_IDLE then
                end_event <= not end_event;
            end if;
        end if;
    end process;

busy_handler:  -- CHANGED
    process (baud_clk)
    begin
        if rising_edge (baud_clk) then
            if start_tx = '1' and bit_buf = BB_IDLE then
                internal_busy <= '1';
            elsif bit_buf = BB_IDLE then
                internal_busy <= '0';
            end if;
        end if;
    end process;

do_transmit:
    process (baud_clk)
    begin
        if rising_edge(baud_clk) then 
            if start_tx = '1'  and bit_buf = BB_IDLE then
                bit_buf <=  '1' & byte_to_transmit & '0';
            elsif bit_buf /= BB_IDLE then
                bit_buf <= '0' & bit_buf(9 downto 1);
            end if;
        end if;
    end process;

    serial_out <= bit_buf(0);

end architecture;

This gives:

Note that the internal_busy signal is used to determine when the back edge of busy occurs (distinguishing between the idle pattern in bit_buf when transmitting or not).

The poke signal has been shortened by modifying Glue to prove the width of poke (send) can be arbitrary:

architecture behavioural of Glue is
    signal divider:  unsigned(29 downto 0) := (others => '0'); -- init val
    signal poke:    std_logic := '0';  -- ADDED
begin
    LED(1) <= '0';

    poke <= divider(17), '0' after 10 us;  -- ADDED
ser_tx:  
    entity work.SerialTX  -- ADDED work prefix to make selected name
        port map (
            baud_clk => divider(12),
            -- byte_to_transmit => std_ulogic_vector(divider(29 downto 22)),
            byte_to_transmit => std_logic_vector(divider(25 downto 18)),-- sim
            poke => poke, -- WAS divider(20), for simulation
            busy => LED(0),
            serial_out => tx
        );

(No, that complex waveform representing a singleshot on the new signal poke is not synthesis eligible.)

这篇关于VHDL(Xilinx工具链)正因“数组修整”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆