?? rec_buf.vhd
字號:
-- RECEIVE BLOCK
library ieee;
use ieee.std_logic_1164.all;
entity rec_buf is
port(rxclk : in std_logic;
ciport : in std_logic_vector(7 downto 0);
miport : in std_logic_vector(7 downto 0);
syn1port : in std_logic_vector(7 downto 0);
syn2port : in std_logic_vector(7 downto 0);
statusport : in std_logic_vector(7 downto 0);
writeport : out std_logic_vector(7 downto 0);
rxrdy : out std_logic;
rxd : in std_logic;
syndet : inout std_logic;
parity_error : out std_logic;
framing_error : out std_logic;
overrun_error : out std_logic;
syndet_status : out std_logic;
status_read : in std_logic;
data_read : in std_logic;
rxrdy_status : out std_logic );
end rec_buf;
architecture rec_buf_arc of rec_buf is
type serial1 is ( start, dbits, parity, stop );
type serial2 is ( syn1det, syn2det, dbits, parity );
type serial3 is ( stop, dbits, parity );
signal currrxd1 : serial1;
signal nextrxd1 : serial1;
signal currrxd2 : serial2;
signal nextrxd2 : serial2;
signal currrxd3 : serial3;
signal nextrxd3 : serial3;
signal holdreg : std_logic_vector(7 downto 0):="11111111";
signal i : integer:=0;
signal j : integer:=0;
signal k : integer:=0;
signal len : integer;
signal width : integer:=2;
signal baud : integer;
signal count : integer:= 1;
signal par_err : std_logic:='0';
signal rxreg_full: std_logic:='0';
signal syndet_in : std_logic:='0';
signal syndet_out: std_logic:='0';
signal brkdet : std_logic:='0';
signal brk : integer:=0;
signal rxrdy_in : std_logic:='0';
begin
len <= 5 when miport(3 downto 2) = "00" else
6 when miport(3 downto 2) = "01" else
7 when miport(3 downto 2) = "10" else
8;
baud <= 1 when miport(1 downto 0) = "01" else
16 when miport(1 downto 0) = "10" else
64 when miport(1 downto 0) = "11" else
1;
rxrdy <= rxrdy_in;
rxrdy_status <= rxrdy_in;
process( rxclk )
begin
currrxd1 <= nextrxd1;
currrxd2 <= nextrxd2;
currrxd3 <= nextrxd3;
end process;
process ( rxclk )
begin
if rxclk = '0' and rxclk'event then
if miport(1 downto 0) = "01" then
count <= baud/2;
elsif miport(1) = '1' then
if count = baud then
count <= 1;
else
count <= count + 1;
end if;
end if;
end if;
end process;
process ( rxclk, status_read )
variable rxreg : std_logic_vector(7 downto 0):="11111111";
begin
if status_read = '1' then
syndet_out <= '0';
end if;
if rxclk = '1' and rxclk'event and ciport(2) = '1' then
if miport(1 downto 0) /= "00" and brkdet = '0' then
if count = baud/2 then
case currrxd1 is
when start =>
if rxd = '0' then
nextrxd1 <= dbits;
i <= 0;
else
nextrxd1 <= start;
end if;
when dbits =>
rxreg(i) := rxd;
if i <= len-2 then
i <= i + 1;
nextrxd1 <= dbits;
elsif miport(4) = '1' then
i <= 0;
nextrxd1 <= parity;
else
i <= 0;
nextrxd1 <= stop;
end if;
when parity =>
i <= 0;
nextrxd1 <= stop;
when stop =>
i <= 0;
if rxd = '1' then
nextrxd1 <= start;
end if;
nextrxd1 <= start;
end case;
end if;
elsif miport(1 downto 0) = "00" and miport(6) = '0' then
case currrxd2 is
when syn1det =>
if j <= len-1 then
syndet_out <= '0';
rxreg(j) := rxd;
j <= j + 1;
else
rxreg(len-1 downto 0) := rxd & rxreg(len-1 downto 1) ;
end if;
if rxreg(len-1 downto 0) = syn1port(len-1 downto 0) and j >= len-1 then
j <= 0;
if miport(7) = '0' then
syndet_out <= '0';
if miport(4) = '1' then
nextrxd2 <= parity;
else
nextrxd2 <= syn2det;
end if;
else
syndet_out <= '1';
if miport(4) = '1' then
nextrxd2 <= parity;
else
nextrxd2 <= dbits;
end if;
end if;
else
syndet_out <= '0';
nextrxd2 <= syn1det;
end if;
when syn2det =>
if j <= len-1 then
syndet_out <= '0';
rxreg(j) := rxd;
j <= j + 1;
end if;
if j = len-1 then
if rxreg(len-1 downto 0) = syn2port(len-1 downto 0) then
syndet_out <= '1';
if miport(4) = '1' then
nextrxd2 <= parity;
else
nextrxd2 <= dbits;
end if;
else
syndet_out <= '0';
nextrxd2 <= syn1det;
end if;
else
syndet_out <= '0';
nextrxd2 <= syn2det;
end if;
when dbits =>
rxreg(j) := rxd;
if j <= len-2 then
j <= j + 1;
nextrxd2 <= dbits;
elsif miport(4) = '1' then
j <= 0;
nextrxd2 <= parity;
elsif syndet_out = '1' then
j <= 0;
nextrxd2 <= dbits;
elsif syndet_out = '0' then
j <= 0;
nextrxd2 <= syn1det;
end if;
when parity =>
j <= 0;
if syndet_out = '1' then
nextrxd2 <= dbits;
elsif syndet_out = '0' then
if rxreg(len-1 downto 0) = syn1port(len-1 downto 0) then
nextrxd2 <= syn2det;
else
nextrxd2 <= syn1det;
end if;
end if;
end case;
elsif miport(1 downto 0) = "00" and miport(6) = '1' then
case currrxd3 is
when dbits =>
rxreg(k) := rxd;
if k <= len-2 then
k <= k + 1;
nextrxd3 <= dbits;
elsif miport(4) = '1' then
k <= 0;
nextrxd3 <= parity;
else
k <= 0;
nextrxd3 <= dbits;
end if;
when parity =>
k <= 0;
nextrxd3 <= dbits;
when stop =>
k <= 0;
if syndet_in = '1' then
nextrxd3 <= dbits;
elsif syndet_in = '0' then
nextrxd3 <= stop;
end if;
end case;
end if;
holdreg <= rxreg;
end if;
end process;
process ( rxclk, currrxd1,currrxd2, currrxd3,ciport )
variable par: std_logic:='0';
begin
if ciport(4) = '1' then
parity_error <= '0';
end if;
if rxclk = '1' and rxclk'event then
if currrxd1 = parity or currrxd2 = parity or currrxd3 = parity then
for l in 0 to len-1 loop
par := par xor holdreg(l);
end loop;
parity_error <= (par xor rxd);
end if;
end if;
end process;
process ( rxclk, currrxd1, ciport )
begin
if ciport(4) = '1' then
framing_error <= '0';
end if;
if rxclk = '1' and rxclk'event then
if miport(1 downto 0) /= "00" then
if currrxd1 = stop and rxd = '1' then
framing_error <= '0';
elsif currrxd1 = stop and rxd = '0' then
framing_error <= '1';
end if;
end if;
end if;
end process;
process ( i, currrxd1, currrxd2, currrxd3, rxclk, ciport )
begin
if ciport(4) = '1' then
overrun_error <= '0';
end if;
if rxclk = '1' and rxclk'event then
if miport(1 downto 0) /= "00" then
if currrxd1 = stop then
if rxrdy_in = '1' then
overrun_error <= '1';
end if;
rxreg_full <= '1';
else
rxreg_full <= '0';
end if;
elsif miport(1 downto 0) = "00" and miport(6) = '0' then
if currrxd2 = dbits and j= len-1 then
if rxrdy_in = '1' then
overrun_error <= '1';
end if;
rxreg_full <= '1';
else
rxreg_full <= '0';
end if;
elsif miport(1 downto 0) = "00" and miport(6) = '1' then
if currrxd3 = dbits and k = len-1 then
if rxrdy_in = '1' then
overrun_error <= '1';
end if;
rxreg_full <= '1';
else
rxreg_full <= '0';
end if;
end if;
end if;
end process;
process ( rxclk, rxreg_full )
begin
if rxreg_full = '1' then
writeport <= holdreg;
end if;
end process;
process ( rxreg_full, data_read, ciport(2) )
begin
if rxreg_full = '1' then
rxrdy_in <= '1';
elsif data_read = '1' then
rxrdy_in <= '0';
elsif ciport(2) = '0' then
rxrdy_in <= '0';
end if;
end process;
process (syndet_out, status_read, miport, rxclk, brkdet )
begin
if miport(1 downto 0) = "00" and miport(6) = '0' then
if status_read = '1' then
syndet <= '0';
syndet_status <= '0';
else
syndet <= syndet_out;
syndet_status <= syndet_out;
end if;
elsif miport(1 downto 0) /= "00" then
syndet <= brkdet;
syndet_status <= brkdet;
else
syndet_status <= 'Z';
syndet <= 'Z';
end if;
end process;
process ( syndet, miport, rxclk, status_read)
begin
if miport(1 downto 0) = "00" and miport(6) = '1' then
syndet_in <= syndet;
if status_read = '1' then
syndet_status <= '0';
elsif syndet = '1' then
syndet_status <= '1';
end if;
else
syndet_status <= 'Z';
syndet_in <= 'Z';
end if;
end process;
process ( rxclk )
begin
if rxclk = '1' and rxclk'event then
if miport(1 downto 0) /= "00" and count = baud/2 then
if rxd = '0' then
brk <= brk + 1;
else
brk <= 0;
end if;
end if;
end if;
end process;
process( miport, len )
variable w : integer:=0;
begin
if miport(1 downto 0) /= "00" then
w := len + 2;
if miport(4) = '1' then
w := w + 1;
end if;
if miport(7 downto 6) = "10" or miport(7 downto 6) = "11" then
w := w + 1;
end if;
width <= w + w;
end if;
end process;
process ( brk, rxd )
begin
if rxd = '1' then
brkdet <= '0';
elsif brk >= width then
brkdet <= '1';
else
brkdet <= '0';
end if;
end process;
end rec_buf_arc;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -