並串轉換之VHDL 源程序

admin @ 2014-03-26 , reply:0

概述
       昨天在論壇上看到有人帖出了他寫的並串轉換VHDL代碼,但是他自己說有問題,但是不知道怎麼改。我大概看了一下,發現思路……

        昨天在論壇上看到有人帖出了他寫的並串轉換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;

       寫完一看,一個並串轉換居然搞了這麼大,有點失敗。但是整個代碼已經通過了后模擬,而且思路還是比較清楚的,可靠性和穩定性方面也應該沒有問題滴,呵呵。不過說老實話,裡面有些信號是確實可以去掉的,不過後來就懶得改了。如果誰想要實際的工程中用的話可以改一下。好了,收工,今天還要去未央湖。。。




[admin via 研發互助社區 ] 並串轉換之VHDL 源程序已經有1738次圍觀

http://cocdig.com/docs/show-post-43382.html