VHDL(Xilinx工具链)I';I’我被“打倒”;“阵列修剪”;
我有一个两个文件的VHDL项目,我有初学者的困难 它采用系统时钟,并使用30位时钟除法器(其中我只使用少量非连续位)来驱动基本串行端口模块(仅输出TX)模块周期性地吐出8位字符 似乎在合成过程中,优化器删除了许多基本信号,这是我没有预料到的 顶级文件“Glue.vhd”…VHDL(Xilinx工具链)I';I’我被“打倒”;“阵列修剪”;,vhdl,compiler-warnings,synthesis,Vhdl,Compiler Warnings,Synthesis,我有一个两个文件的VHDL项目,我有初学者的困难 它采用系统时钟,并使用30位时钟除法器(其中我只使用少量非连续位)来驱动基本串行端口模块(仅输出TX)模块周期性地吐出8位字符 似乎在合成过程中,优化器删除了许多基本信号,这是我没有预料到的 顶级文件“Glue.vhd”… library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use ieee.std_logic_unsigned.all; entity Glu
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;
IEEE库;
使用IEEE.std_logic_1164.all;
使用IEEE.numeric_std.all;
使用ieee.std_logic_unsigned.all;
实体胶是
港口(
clk:标准逻辑中;
tx:输出标准逻辑;
LED:输出标准逻辑向量(1到0)
);
末端实体胶;
胶水的建筑性能是
信号除法器:无符号(29至0);
开始
LED(1)分配器(12),
字节到传输=>标准逻辑向量(除法器(29到22)),
戳=>分隔器(20),
忙=>LED(0),
串行输出=>tx
);
时钟:进程(时钟)
开始
如果(上升沿(clk)),则
divider虽然user1155120在您应该指定库或进行组件绑定的意义上是正确的,但是您的工具显然找到了正确的实体,因为这就是优化逻辑的地方
第一件事,不要用
use IEEE.numeric_std.all;
use ieee.std_logic_unsigned.all;
一起。除处理旧代码外,您应该使用数字_std
真正的问题有两个方面:
- 你没有初始化你的计数器变量,它也不正确
- 您的输入数据永远不会进入并行加载移位寄存器,因此会被修剪
您希望计数器以什么值启动?IIRC,未初始化的整数类型将采用其范围内的最低有效值。然而,在任何情况下,最好明确开始。然而,实际上FPGA中没有整数,只有冷的、硬的触发器。0到10的范围使用至少4位,因此使用4个触发器。然而,从0到“-1”将下溢并环绕到15,而不是您可能期望的10。
internal_busy
是一个触发器,但也没有初始化。我之所以说是有意的,是因为它实际上是由位计数器
异步重置的。这种异步重置本身是有问题的,几乎肯定不是您想要的:
busy_handler : process(poke) is -- <-- wrong sensitivity list
begin
if(rising_edge(poke)) then
internal_busy <= '1';
end if;
if(bit_counter = 0) then -- <-- not clocked
internal_busy <= '0';
end if;
end process busy_handler;
如果没有这种逻辑,bit\u buf
实际上将是9'h000
(Xilinx工具假定的值——您没有给出任何值!)。这是以下几行试图告诉您的:
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: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.
字节到字节传输
未使用且不是顶级块的一部分,它将不会被保留
分频器(从29到22)
连接到字节到发送
。由于该端口将被移除,所以可以优化掉最后使用的触发器、除法器(20)
之后的所有触发器
时钟警告:
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.
总之,您应该按照Brian Drummond的建议,在合成之前编写一个测试台并模拟您的设计
在编写实现之前编写测试台的一部分通常是有帮助的,因为这将迫使您在实际编写组件之前考虑组件的接口以及您期望它如何反应。而user1155120在您应该指定库或进行组件绑定的意义上是正确的,您的工具显然找到了正确的实体,因为这就是优化逻辑的地方
第一件事,不要用
use IEEE.numeric_std.all;
use ieee.std_logic_unsigned.all;
一起。除处理旧代码外,您应该使用数字_std
真正的问题有两个方面:
- 你没有初始化你的计数器变量,它也不正确
- 您的输入数据永远不会进入并行加载移位寄存器,因此会被修剪
您希望计数器以什么值启动?IIRC,未初始化的整数类型将采用其范围内的最低有效值。然而,在任何情况下,最好明确开始。然而,实际上FPGA中没有整数,只有冷的、硬的触发器。0到10的范围使用至少4位,因此使用4个触发器。然而,从0到“-1”将下溢并环绕到15,而不是您可能期望的10。
internal_busy
是一个触发器,但也没有初始化。我之所以说是有意的,是因为它实际上是由位计数器
异步重置的。这种异步重置本身是有问题的,几乎肯定不是您想要的:
busy_handler : process(poke) is -- <-- wrong sensitivity list
begin
if(rising_edge(poke)) then
internal_busy <= '1';
end if;
if(bit_counter = 0) then -- <-- not clocked
internal_busy <= '0';
end if;
end process busy_handler;
如果没有这种逻辑,bit\u buf
实际上将是9'h000
(Xilinx工具假定的值——您没有给出任何值!)。这是以下几行试图告诉您的:
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: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.
字节到字节传输
未使用且不是顶级块的一部分,它将不会被保留
分频器(从29到22)
连接到字节到发送
。由于该端口将被移除,所以可以优化掉最后使用的触发器、除法器(20)
之后的所有触发器
时钟警告:
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.
总之,您应该按照Brian Drummond的建议,在合成之前编写一个测试台并模拟您的设计
在编写实现之前编写测试台的一部分通常是有帮助的,因为这将迫使您在实际编写组件之前考虑组件的接口以及您期望它如何反应。您可以模拟您的设计,它处于复杂性的边缘,比猜测在FPGA中合成和加载时为什么不工作要容易得多。也可以制作
可以去掉位计数器,因为您有一个10位位移位寄存器
这样做的方式是,您设置一个默认模式,该模式被识别为“空”,并且
clk_en_p: process (clk) is
begin
if (rising_edge(clk)) then
if (clk_en = '1') then
my_signal <= assignment;
end if;
end if;
end process clk_en_p;
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;
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;
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
);