在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 2775|回复: 4

一个简单的fifo请大家帮忙简化一下

[复制链接]
发表于 2004-3-17 21:07:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
初学vhdl,请大家帮忙简化仿真一些
请问接受端使用原始的时钟clk和fsyn是否能正确的采样串行输出数据?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity fifo is
port(clk:in std_logic;--原始时钟
fsynut std_logic;--帧同步
datain:in std_logic_vector(7 downto 0);--并行输入数据
pcmoutut std_logic;--串行输出数据
n_clkut std_logic;--反向输出时钟
we:in std_logic;--写允许信号
oe:in std_logic;--片选信号
clearfifo:in std_logic;--清空fifo
address:in std_logic_vector(7 downto 0)--fifo地址
);
end fifo;
architecture a of fifo is
signal counter:std_logic_vector(3 downto 0);--用来产生帧同步
signal data:std_logic_vector(31 downto 0);--用来保存输入数据
signal interior_fsyn:std_logic;--内部使用的帧同步
signal write_signal:std_logic;--用来标示写地址和写数据
signal temp_address:std_logic_vector(7 downto 0);--保存地址
signal number:std_logic_vector(4 downto 0);--计数输出数据
signal interior_clk:std_logic;--内部移位输出使用的时钟为原始时钟反相
signal pcmout:std_logic;
begin
n_clk<=not clk;
interior_clk<=not clk;
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------
write_signal<=we or oe;--产生写控制信号
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- 锁存地址
process(write_signal,clearfifo)
begin
if clearfifo='1'then
temp_address<="00000000";
elsif falling_edge(write_signal)then
temp_address<=address;
end if;
end process;
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
counter<=counter+1;
end if;
end process;
-----------------------------------------------------------------------------------
------------------------------------------------------------------------------------
--产生帧同步
process(counter)
begin
if counter<"1000" then
fsyn<='1';
interior_fsyn<='1';
else
fsyn<='0';
interior_fsyn<='0';
end if;
end process;
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--存储输入数据
process(write_signal,clearfifo)
begin
if clearfifo='1' then
data<="00000000000000000000000000000000";
elsif rising_edge(write_signal) then
if temp_address="10000011" then--对应地址0x83
data(31 downto 24)<=datain;
    elsif temp_address="10000010"then--对应地址0x82
data(23 downto 16)<=datain;
elsif temp_address="10000001"then--对应地址0x81
data(15 downto 8)<=datain;
    elsif temp_address="10000000"then--对应地址0x80
data(7 downto 0)<=datain;
end if;
end if;
end process;
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--PCM输出先输出高位
--输出数据
process(interior_clk,clearfifo)
begin
if clearfifo='1' then
number<="11111";
elsif rising_edge(interior_clk)then
if interior_fsyn='1'then
number<=number-1;
case number is
when "11111"=>
pcmout<=data(31);
when "11110"=>
pcmout<=data(30);
when "11101"=>
pcmout<=data(29);
when "11100"=>
pcmout<=data(28);
when "11011"=>
pcmout<=data(27);
when "11010"=>
pcmout<=data(26);
when "11001"=>
pcmout<=data(25);
when "11000"=>
pcmout<=data(24);
when "10111"=>
pcmout<=data(23);
when "10110"=>
pcmout<=data(22);
when "10101"=>
pcmout<=data(21);
when "10100"=>
pcmout<=data(20);
when "10011"=>
pcmout<=data(19);
when "10010"=>
pcmout<=data(18);
when "10001"=>
pcmout<=data(17);
when "10000"=>
pcmout<=data(16);
when "01111"=>
pcmout<=data(15);
when "01110"=>
pcmout<=data(14);
when "01101"=>
pcmout<=data(13);
when "01100"=>
pcmout<=data(12);
when "01011"=>
pcmout<=data(11);
when "01010"=>
pcmout<=data(10);
when "01001"=>
pcmout<=data(9);
when "01000"=>
pcmout<=data(8);
when "00111"=>
pcmout<=data(7);
when "00110"=>
pcmout<=data(6);
when "00101"=>
pcmout<=data(5);
when "00100"=>
pcmout<=data(4);
when "00011"=>
pcmout<=data(3);
when "00010"=>
pcmout<=data(2);
when "00001"=>
pcmout<=data(1);
when "00000"=>
pcmout<=data(0);
when others=>
pcmout<='Z';
end case;
end if;
end if;
end process;
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------
end a;
发表于 2004-3-18 14:30:25 | 显示全部楼层

一个简单的fifo请大家帮忙简化一下

提几个小意见:
1。锁存地址和数据部分:
elsif falling_edge(write_signal)then
最好不要那write_signal当时钟来用,它应该是个控制信号。
2。PCM数据输出:
elsif rising_edge(interior_clk)then
最好不要在时钟上加反相再用,你可以直接用下降沿触发。
pcmout实际上是个并串转化的输出,不用这么复杂。
直接可以用:
datatmp(31 downto 0)<=datatmp(30 downto 0) & '0';
pcmout<=datatmp(31);
类似这样的写法,具体怎么做你可以根据你的实际情况考虑。
你原来的写法会产生一个32选1的MUX,对你的fmax影响很大。
 楼主| 发表于 2004-3-18 17:31:22 | 显示全部楼层

一个简单的fifo请大家帮忙简化一下

谢谢版主大人啊
 楼主| 发表于 2004-3-18 17:46:40 | 显示全部楼层

一个简单的fifo请大家帮忙简化一下

说明一下,首先0x83~0x80地址对应的空间相当于RAM,所以write_signal是使用RAM的片选信号ce和写信号we相或后产生的,在下降沿锁存地址,再上升沿锁存输入的数据,所以不是当作时钟用的。
datatmp(31 downto 0)<=datatmp(30 downto 0) & '0';
pcmout<=datatmp(31);
这样做的前提是要将pcm_out传给datatmp,可是在什么情况下传递啊
我开始也是用移位做的,可是没法把pcm_out传给datatmp,因为我要在四个连续的帧同步中
把RAM中的四个字节依次移位输出。
发表于 2004-3-18 20:56:58 | 显示全部楼层

一个简单的fifo请大家帮忙简化一下

if falling_edge(write_signal)then
这种写法反映到硬件上就是将write_signal接到触发器的时钟端。这样做不好。
移位寄存器一般要一个load信号
比如:
process(clk)
if count=31 then
   datatmp<=data;
else
   datatmp(31 downto 0)<=datatmp(30 downto 0) & '0';
end if;
end process;
pcmout<=datatmp(31);
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-20 04:39 , Processed in 0.027492 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表