微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 求助,串转并(VHDL)

求助,串转并(VHDL)

时间:10-02 整理:3721RD 点击:
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,下图为程序的流程图

这么牛逼的论坛没有一个人回复啊!

一个串转并用得着搞得这么复杂?

您还有更简单的?呵呵,那您给我一个吧,输入信号就是clk,reset,datain,输出信号时dataout

大哥,你说有谁会有闲心思看这么一段缺少注释的代码?
代码是慢慢调出来的
问问周边的人吧
论坛不适合问这类问题

太长了

good
good
good
good
good

好长啊~
把仿真波形一点点调出来看嘛,包括其中的信号和变量,总会找到原因的。

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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top