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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 5213|回复: 8

求助,串转并(VHDL)

[复制链接]
发表于 2009-9-7 16:40:36 | 显示全部楼层 |阅读模式

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

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

x
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity txd is
port (
        clk,reset: in std_logic;
        errin: in std_logic_vector(3 downto 0);
        adin: in std_logic_vector(3 downto 0);
        data: in std_logic;
        tx: out std_logic;
        dataout: out std_logic_vector(6 downto 0)
     );
end;
architecture txdd of txd is
signal tp,carry,load,datain: std_logic;
signal reg1,reg2:std_logic_vector(7 downto 0);
signal gg : integer range 0 to 15;
signal clk1,err1,err2,err3,err4:  std_logic;
signal adintemp : std_logic_vector(3 downto 0);
signal yy: std_logic_vector(2 downto 0);
begin
datain<= not data;
  process(clk,reset)
    variable hh: integer range 0 to 7;
    begin
      if reset='1' then
        hh:=0;
      elsif clk'event and clk='1' then
        if hh=7 then
           hh:=0;
        else hh:=hh+1;
        end if;
    yy<=conv_std_logic_vector(hh,3);
      end if;
end process;
      clk1<=yy(2);
process( clk1,reset)
    variable cntt: integer range 0 to 15;   
   begin
           if reset ='1' then   
                cntt:=0;
    adintemp<="0000";
    err1<='0';
    err2<='0';
    err3<='0';
    err4<='0';
            elsif clk1'event and clk1='1' then
               if cntt= 15 then
                    cntt:=0;
     adintemp<=adin;
     err1<=errin(0);
     err2<=errin(1);
     err3<=errin(2);
     err4<=errin(3);
               else
                cntt:=cntt+1;
              end if;
           end if;
         gg<=cntt;
   end process;
process(clk1)
     begin
        if clk1'event and clk1='0' then
         case gg is
              when 0 => tx<='1';
              when 1 => tx<='0';
              when 2 => tx<=err1 ;
              when 3 => tx<=err2 ;
              when 4 => tx<=err3 ;
              when 5 => tx<=err4 ;
              when 6 => tx<=adintemp(0) ;
       when 7 => tx<=adintemp(1) ;
              when 8 => tx<=adintemp(2) ;
              when 9 => tx<=adintemp(3) ;
        when others => tx<='1';
           end case ;
         end if;
        end process;
  process(clk,reset)
  variable cnt:integer range 0 to 8;
  begin
    if reset='1' then
       tp<='1';
       cnt:=0;
      
    elsif (clk'event and clk='1') then
      if datain = '0' and load='1' then
         if cnt=8 then  
            cnt:=0;
         else cnt:=cnt+1;
         end if;
         case cnt is
         when 1 => reg1(0)<=datain;
         when 2 => reg1(1)<=datain;
         when 3 => reg1(2)<=datain;
         when 4 => reg1(3)<=datain;
         when 5 => reg1(4)<=datain;
         when 6 => reg1(5)<=datain;
         when 7 => reg1(6)<=datain;
         when 8 => reg1(7)<=datain;
         when others => null;
         end case;
         tp<=reg1(5) or reg1(6) or reg1(7);  
        end if;
end if;
end process;

process(clk,reset,tp)----每隔16个clk采集下一位数据
   variable cnt1:integer range 0 to 15;
   begin
   if reset='1' then
      cnt1:=0;
      carry<='0';
   elsif tp='0' then
     if clk'event and clk='1' then
        if cnt1=15 then
           cnt1:=0;
           carry<='1';
        else cnt1:=cnt1+1;
             carry<='0';
        end if;
     end if ;
   end if;
end process;
process(carry,reset)----判断是否接收完一帧数据,load为1即为接收完毕;
   variable cnt2:integer range 0 to 14;
   begin
     if reset='1' then
        cnt2:=0;
        load<='1';
     elsif carry'event and carry='1' then
         if cnt2=14 then
            cnt2:=0;
            load<='1';
         else cnt2:=cnt2+1;
            load<='0';
        end if;
        case cnt2 is
        when 1 => reg2(0)<=datain;
        when 2 => reg2(1)<=datain;
        when 3 => reg2(2)<=datain;
        when 4 => reg2(3)<=datain;
        when 5 => reg2(4)<=datain;
        when 6 => reg2(5)<=datain;
        when 7 => reg2(6)<=datain;
        when others => null;
        end case;
    end if;
end process;   
process(load)
   begin
     if load='1' then
        dataout(6 downto 0)<=reg2(6 downto 0);
     end if;
end process;
  end txdd;

这是我自己写的并转串和串转并得代码,此段程序的目的是:先由CPLD外部输入8位并行数据,然后将这8位并行数据转换为16位串行数据,其中起始位为0,后面8位为CPLD输入的8位并行数据,其余的后面几位都为1,然后通过一根光纤实现自发自收,将串行码转换为并行码,串转并得流程是,先确认起始位0,对起始位0进行8次取样(计数到起始位0的中心点),如果几次取样为0,则开始读取后8位的数据,第一个计数器cnt1是计数16个clk到达下一个数据的中心点进行采样,进位为carry;第二个计数器cnt2是对carry进行计数,当计数到14时,表示此帧数据(16位)已经接收完,load为1时,将采集到得数据送到dataout中,但是我自己编写的串转并这一段代码,实现不了串转并得功能,请高手指点一下,哪个地方出错了,晶振为32M,下图为程序的流程图

                               
登录/注册后可看大图


[ 本帖最后由 360883850 于 2009-9-7 16:42 编辑 ]
 楼主| 发表于 2009-9-7 19:31:08 | 显示全部楼层
这么牛逼的论坛没有一个人回复啊!!!
发表于 2009-9-8 08:30:04 | 显示全部楼层
一个串转并用得着搞得这么复杂?
 楼主| 发表于 2009-9-8 08:34:40 | 显示全部楼层
您还有更简单的?呵呵,那您给我一个吧,输入信号就是clk,reset,datain,输出信号时dataout

[ 本帖最后由 360883850 于 2009-9-8 09:48 编辑 ]
发表于 2009-9-8 11:34:23 | 显示全部楼层
大哥,你说有谁会有闲心思看这么一段缺少注释的代码?
代码是慢慢调出来的
问问周边的人吧

论坛不适合问这类问题
发表于 2009-9-12 01:58:26 | 显示全部楼层
太长了
发表于 2009-9-12 04:49:03 | 显示全部楼层
good
good
good
good
good
发表于 2009-9-12 13:51:10 | 显示全部楼层
好长啊~
把仿真波形一点点调出来看嘛,包括其中的信号和变量,总会找到原因的。
发表于 2009-9-12 15:30:43 | 显示全部楼层

你的串并转换的设计思想有错

首先,你的同步用8倍过采样去做,只能实现位同步,但是帧同步你没法实现,也就是说你的串并转换程序无法断定什么时间出现的比,特位是第一位,在你的设计中用0位后一位为第一位,会被正常数据中的0搞乱.
再有,你用光纤做通信,那么你尾加全"1"是不对的.
明确的说,你不是通信专业的,对通信你不理做.好好读点书吧,你不限在你学校学的专业上.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

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

GMT+8, 2024-11-17 04:36 , Processed in 0.025104 second(s), 10 queries , Gzip On, Redis On.

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