我已经实现了一个4 FIFO队列和一个搜索FIFO索引的块,当发现一个非空的FIFO将提取数据结束时,它将串行发送它.
这是代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Serialize is
port
(
TX : out std_logic_vector(1 downto 0);
RESET, CLK, We1, We2, We3, We4 : in std_logic;
--
DATA_IN_A, DATA_IN_B, DATA_IN_C, DATA_IN_D : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
fifo_full1, fifo_full2, fifo_full3, fifo_full4 : out std_logic;
--
SendPackage : out std_logic
);
end Serialize;
architecture rtl of Serialize is
signal step, nr : integer:=0;
signal enl : std_logic := '0';
signal temp : std_logic_vector(31 downto 0);
--signal txx : std_logic_vector(1 downto 0);
TYPE sr_length IS ARRAY (0 to 3) OF STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL queue, queue1, queue2, queue3 : sr_length;
signal ptr, ptr1, ptr2, ptr3 : integer:= 0;
-- signal tmp : std_logic_vector(1 downto 0);
signal i_a, i_b : std_logic;
signal q_a, q_b, q_c, q_d : std_logic_vector(31 downto 0);
--signal nr : integer := 0;
begin
process(CLK, RESET, We1, We2, We3, We4, DATA_IN_A, DATA_IN_B, DATA_IN_C, DATA_IN_D) is
--variable step, nr : integer:=0;
--variable enl : std_logic := '0';
--variable temp : std_logic_vector(31 downto 0);
begin
if(RESET = '1') then
SendPackage <= '0';
TX<= "00";
-- busy <= '0';
--step:= 0;
--temp := X"00000000";
--enl := '0';
step<= 1;
temp <= X"00000000";
enl <= '0';
ptr <= 0;
ptr1 <= 0;
ptr2 <= 0;
ptr3 <= 0;
fifo_full1 <= '0';
fifo_full2 <= '0';
fifo_full3 <= '0';
fifo_full4 <= '0';
--nr := 0;
nr <= 0;
for i in 0 to 2 loop
queue(i)<=X"00000000";
queue1(i)<=X"00000000";
queue2(i)<=X"00000000";
queue3(i)<=X"00000000";
end loop;
end if;
if(CLK'event) then
if(CLK = '1')then
--SendPackage <= '0';
if(We1 = '1' or We2 = '1' or We3 = '1' or We4 = '1')then
IF (We1 = '1' and ptr <= 3) THEN
for i in 0 to 2 loop
queue(i + 1) <= queue(i);
end loop;
queue(0) <= DATA_IN_A;
ptr <= ptr+ 1;
END IF;
IF (We2 = '1' and ptr1 <= 3) THEN
for i in 0 to 2 loop
queue1(i + 1) <= queue1(i);
end loop;
queue1(0) <= DATA_IN_B;
ptr1 <= ptr1+ 1;
END IF;
IF (We3 = '1' and ptr2 <= 3) THEN
for i in 0 to 2 loop
queue2(i + 1) <= queue2(i);
end loop;
queue2(0) <= DATA_IN_C;
ptr2 <= ptr2 + 1;
END IF;
IF (We4 = '1' and ptr3 <= 3) THEN
for i in 0 to 2 loop
queue3(i + 1) <= queue3(i);
end loop;
queue3(0) <= DATA_IN_D;
--if(ptr3<=3)then ptr3 <= ptr3 + 1; end if;
ptr3 <= ptr3 + 1;
END IF;
elsif(enl = '1')then
SendPackage <= '0';
--if(step = 0) then step <= step + 1; end if;
if(step = 1) then TX <= temp(1 downto 0); i_b <= '1'; step <= step + 1; end if;
if(step = 2) then TX <= temp(3 downto 2); i_b <= '0'; step <= step + 1; end if; --step <= step + 1;
if(step = 3) then TX <= temp(5 downto 4); step <= step + 1; end if;
if(step = 4) then TX <= temp(7 downto 6); step <= step + 1; end if;
if(step = 5) then TX <= temp(9 downto 8); step <= step + 1; end if;
if(step = 6) then TX <= temp(11 downto 10); step <= step + 1; end if;
if(step = 7) then TX <= temp(13 downto 12); step <= step + 1; end if;
if(step = 8) then TX <= temp(15 downto 14); step <= step + 1; end if;
if(step = 9) then TX <= temp(17 downto 16); step <= step + 1; end if;
if(step = 10) then TX <= temp(19 downto 18); step <= step + 1; end if;
if(step = 11) then TX <= temp(21 downto 20); step <= step + 1; end if;
if(step = 12) then TX <= temp(23 downto 22); step <= step + 1; end if;
if(step = 13) then TX <= temp(25 downto 24); step <= step + 1; end if;
if(step = 14) then TX <= temp(27 downto 26); step <= step + 1; end if;
if(step = 15) then TX <= temp(29 downto 28); step <= step + 1; end if;
if(step = 16) then--mai merg un pas pentru a putea transmite tot pachetul. Daca nu pierd 2 biti
TX <= temp(31 downto 30); step <= step + 1; end if;
if(step = 17) then--dupa inca un pas initializez alta trasmitere
--step := 0;
--temp := X"00000000";
--enl := '0';
step <= 1;
temp <= X"00000000";
enl <= '0';
--step <= step + 1;
end if;
i_a <= '1';
--step <= step + 1;
elsif(enl = '0')then
if(nr = 0)then
if(ptr>=1)then
ptr <= ptr - 1;
--temp := queue(ptr-1);
temp <= queue(ptr-1);
q_a <= queue(ptr-1);
SendPackage <= '1';
enl <= '1';
step <= 1;
--enl := '1';
--step := 0;
TX <= "00";
end if;
nr <= nr + 1;
end if;
if(nr = 1)then
if(ptr1>=1)then
ptr1 <= ptr1 - 1;
temp <= queue1(ptr1-1);
q_b <= queue1(ptr1-1);
--temp := queue1(ptr1-1);
SendPackage <= '1';
enl <= '1';
step <= 1;
--enl := '1';
--step := 0;
TX <= "00";
end if;
nr <= nr + 1;
end if;
if(nr = 2)then
if(ptr2>=1)then
ptr2 <= ptr2 - 1;
--temp := queue2(ptr2-1);
temp <= queue2(ptr2-1);
q_c <= queue2(ptr2-1);
SendPackage <= '1';
enl <= '1';
step <= 1;
--enl := '1';
--step := 0;
TX <= "00";
end if;
nr <= nr + 1;
end if;
if(nr >= 3)then
if(ptr3>=1)then
ptr3 <= ptr3 - 1;
temp <= queue3(ptr3-1);
q_d <= queue3(ptr3-1);
--temp := queue3(ptr3-1);
SendPackage <= '1';
enl <= '1';
step <= 1;
nr <= nr + 1;
-- nr := 0;
--enl := '1';
--step := 0;
TX <= "00";
end if;
nr <= 0;
end if;
--if(nr >= 3 )then nr <= 0; end if;
end if;
else
SendPackage <= '0';
i_a <= '0';
end if;
end if;
if(ptr >= 4)then fifo_full1 <= '1'; else fifo_full1 <= '0'; end if;
if(ptr1 >= 4)then fifo_full2 <= '1'; else fifo_full2 <= '0'; end if;
if(ptr2 >= 4)then fifo_full3 <= '1'; else fifo_full3 <= '0'; end if;
if(ptr3 >= 4)then fifo_full4 <= '1'; else fifo_full4 <= '0'; end if;
end process;
end rtl;
Run Code Online (Sandbox Code Playgroud)
它可以正常工作,直到您想要将数据插入一个未满的队列并且传输正在运行.该步骤被省略.因此传输将不起作用.我希望它独立工作.
例如:
step : 1 3 4 5 6 7 8 9 10 11 12 ... 17
_
We :____| |_____________________________________.....
_ _ _ _ _ _ _ _ _ _ _ _
CLK :| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|..
我使用Altium Designer Winter 09工作(在fpga上模拟和实现)
我看到你的答案很少......你发布了大量的代码,希望潜在的回答者能够通过搜索!在你得到更多帮助之前,你必须先将它分解一下.(并整理一下 - 例如,请删除所有注释掉的部分.)
为了调试自己,我建议你首先让一个通道在自己的实体中工作.如果您仍然遇到问题,请编辑您的问题以说明您尝试过的内容以及哪些内容无效.
一旦一个通道工作,您可以使用较小的控制过程实例化其中的4个,以整理这些元素的加载并将正确的输出输出到正确的位置.
在小的阶段建立起来.
您对编码风格的一些评论:
注意:这些完全基于"样式分析",而不是试图修复(或确实复制)任何功能!
首先,删除这两个条款
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Run Code Online (Sandbox Code Playgroud)
你没有使用它们.如果你需要对矢量进行算术运算,请使用ieee.numeric_std和使用unsigned/ signed类型.
在entity,你有4个"版本"的几个信号 - 为什么不用它们std_logic_vector控制的矢量宽度s generic?你可以做类似的事情ptr,ptr1等等(请整数数组-满分BTW使用integers,而不是试图让所有的运算发生上std_logic_vectors)
敏感度列表太复杂了:
process(CLK, RESET, We1, We2, We3, We4, DATA_IN_A, DATA_IN_B, DATA_IN_C, DATA_IN_D) is
Run Code Online (Sandbox Code Playgroud)
你正在编写一个同步的过程与异步复位,所以你只需要CLK和RESET在敏感列表.
你的时钟条件:
if (CLK'event) then
if (CLK = '1') then
Run Code Online (Sandbox Code Playgroud)
有一个更传统的习语:
if rising_edge(clk) then
Run Code Online (Sandbox Code Playgroud)
(并且()在if布尔条件周围没有要求.这是C编程:)
这个循环
for i in 0 to 2 loop
queue(i + 1) <= queue(i);
end loop;
queue(0) <= DATA_IN_A;
Run Code Online (Sandbox Code Playgroud)
可以在一行中完成:
queue <= data_in_a & queue(0 to sr_length'high-1);
Run Code Online (Sandbox Code Playgroud)
任何时候复制和粘贴大量代码,通常都有更好的方法:
if(step = 1) then TX <= temp(1 downto 0); i_b <= '1'; step <= step + 1; end if;
if(step = 2) then TX <= temp(3 downto 2); i_b <= '0'; step <= step + 1; end if;
if(step = 3) then TX <= temp(5 downto 4); step <= step + 1; end if;
Run Code Online (Sandbox Code Playgroud)
可以成为例如:
if (step < 17) then
TX <= temp((step-1)*2+1 downto (step-1)*2);
step <= step + 1;
end if;
i_b <= '0';
if step = 1 then
i_b <= '1';
end if;
Run Code Online (Sandbox Code Playgroud)
如果步骤从0变为16而不是1到17,那将更加整洁!
最后,这些部分:
if(nr = 0)then
if(ptr>=1)then
Run Code Online (Sandbox Code Playgroud)
可在完成for循环,如果ptr...,q_a,q_b等处理数组.
和类似的循环
if(ptr >= 4)then fifo_full1 <= '1'; else fifo_full1 <= '0'; end if;
Run Code Online (Sandbox Code Playgroud)
任何时候你复制,粘贴然后调整大块代码,查找loop,或创建function或procedure封装重复的代码.