VHDL在异步时钟下对一个信号进行修改,有问题,有什么修改的方法吗?
[复制链接]
本帖最后由 haha丶 于 2023-3-27 08:30 编辑
需要将数据包在40M的时钟下写入FIFO中,在240M的时钟下读出数据包。应为读时钟比写时钟块,并且希望每次可以连续读出一个完整的数据包,所以我的想法是在写入端每次检测到包尾的最高位‘01’时,变量var_cnt + 1,这时若var_cnt不为‘0’读使能置高,同时在读出端监测到包尾的最高位‘01’时,变量var_cnt - 1,若var_cnt为‘0’停止读出。测试时在只发送一个数据包的情况下var_cnt在写入端检测到包尾的最高位‘01’时变量var_cnt + 1=1,在读出端测到包尾的最高位‘01’时变量var_cnt - 1=0,在减到‘0’后一个周期又变为‘1’,FIFO也没读出程序陷入死循环。
下图中rxdata30写入FIFO,在检测到包尾最高位‘01’时,cnt由0变1.
下图中fifo_out为FIFO读出数据,在检测到包尾最高位‘01’时,cnt由1变0,但在一个周期后又变为1(写程序时就觉得有问题).
数据包每一帧位宽为30bit,用高两位来区分包头、数据、包尾
这段代码如下,感觉不应该在两个时钟下对一个变量进行修改,该怎么改比较好呢?rxclk为40MHz时钟,rxdata30_1另作它用且正常可以不管。
rx_vr: for i in 0 to 15 generate
begin
process(fe_rst,rxclk,tx_rst,clk240 )
variable var_cnt : txrx5b_type_16;
begin
if (rxclk'event and rxclk = '1') then
if (fe_rst = '1' or tx_rst = '1') then
rxdata30_1(i) <= (others => '0');
else
if (rx_valid(i) = '1' and rx_ready(i) = '1') then
rxdata30_1(i) <= rxdata30(i);
if(rxdata30(i)(29 downto 28) = "01") then
var_cnt(i) := var_cnt(i) + '1';
end if;
end if;
end if;
end if;
if (clk240'event and clk240 = '1') then
if (fe_rst = '1' or tx_rst = '1') then
var_cnt(i) := (others => '0');
else
if (fifo_outdout(i)(29 downto 28) = "01" and fifo_outdout1(i)(29 downto 28) = "00") then --fifo_outdout1 <= fifo_outdout在别的位置写了
var_cnt(i) := var_cnt(i) - '1';
end if;
end if;
end if;
flit_cnt(i) <= var_cnt(i);
end process;
|