并串转换之VHDL 源程序
2012-12-16
标签:

昨天在论坛上看到有人帖出了他写的并串转换VHDL代码,但是他自己说有问题,但是不知道怎么改。我大概看了一下,发现思路还是比较乱的。于是就写下了我自己的并串转换代码。这个并串转换代码是依靠同步状态机来实现其控制的。其实并串转换在实际的电路中使用还是比较多的,尤其在通信线路方面的复用和分解方面,原理上就是一个串并转换和并串转换的过程。举个简单的例子,计算机串口发送数据的过程,如果满足发送条件了,其实就是一个并串转换的过程了。好了,废话不说,看代码就是。

--------------------------------------------------------------------------------

-- Engineer: skycanny

-- Module Name: p2s - Behavioral

-- Tool versions: ISE7.1

-- Description: This module is designed to implement parallel to serial conversion

--------------------------------------------------------------------------------

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity p2s is

port(

reset : in std_logic;

clk : in std_logic;

start : in std_logic; --low active,data_in valid

data_in : in std_logic_vector(7 downto 0);

data_valid : out std_logic; --high active,output data valid

ready : out std_logic; --low active,ready to recieve data

q : out std_logic

);

end p2s;

architecture Behavioral of p2s is

signal reg : std_logic_vector(7 downto 0);

signal cnt : std_logic_vector(3 downto 0);

signal reg_en : std_logic;

signal shift_start : std_logic;

type state is (idle,recieve,shift,finish);

signal current_state, next_state : state;

begin

counter: process(reset,clk,shift_start)

begin

if(reset = '0') then

cnt <= (others => '0');

elsif(clk'event and clk = '1') then

if(shift_start = '0') then

cnt <= cnt 1;

else

cnt <= (others => '0');

end if;

end if;

end process counter;

fsm: block

begin

sync: process(reset,clk)

begin

if(reset= '0') then

current_state <= idle;

elsif(clk'event and clk = '1') then

current_state <= next_state;

end if;

end process sync;

comb: process(current_state,cnt,start)

begin

case current_state is

when idle =>

ready <= '0';

reg_en <= '1';

shift_start <= '1';

data_valid <= '1';

if(start = '0') then

reg_en <= '0';

next_state <= recieve;

else

next_state <= idle;

end if;

when recieve =>

reg_en <= '1';

ready <= '1';

data_valid <= '0';

shift_start <= '0';

next_state <= shift;

when shift =>

reg_en <= '1';

ready <= '1';

data_valid <= '0';

if(cnt = 8) then

shift_start <= '1';

next_state <= finish;

else

shift_start <= '0';

next_state <= shift;

end if;

when finish =>

reg_en <= '1';

ready <= '0';

data_valid <= '1';

shift_start <= '1';

next_state <= idle;

when others =>

next_state <= idle;

end case;

end process comb;

end block fsm;

data_channel: process(reset,clk)

begin

if(reset = '0') then

reg <= (others => '0');

q <= '0';

elsif(clk'event and clk = '1') then

if(reg_en = '0') then

reg <= data_in;

elsif(shift_start = '0') then

q <= reg(7);

for i in 7 downto 1 loop --shift register

reg(i) <= reg(i - 1);

end loop;

reg(0) <= '0';

else

q <= '0';

end if;

end if;

end process data_channel;

end Behavioral;

写完一看,一个并串转换居然搞了这么大,有点失败。但是整个代码已经通过了后仿真,而且思路还是比较清楚的,可靠性和稳定性方面也应该没有问题滴,呵呵。不过说老实话,里面有些信号是确实可以去掉的,不过后来就懒得改了。如果谁想要实际的工程中用的话可以改一下。好了,收工,今天还要去未央湖。。。

可能会用到的工具/仪表
相关文章
推荐文章
热门文章
章节目录
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号