顶层文件
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.uart_1.all;
entity UART is
generic( data_bit:integer:=8;
total_bit:integer:=10;
parity_rule:parity:=even;
full_plus_count:bd_count:=bd9600_fpc;
rise_plus_count:bd_count:=bd9600_hpc);
port (clk:in std_logic;
reset_n:in std_logic;
send: in std_logic;
rxd:in std_logic;
txd:out std_logic;
error1:out std_logic;
send_over:out std_logic;
recv:out std_logic;
recv_buf:out std_logic_vector(7 downto 0);
send_bus:in std_logic_vector(7 downto 0));
end UART;
architecture rtl of UART is
component parity_verifier
generic(data_length:integer:=8;
parity_rule:parity:=even);
port(
source:in std_logic_vector(data_length-1 downto 0);
parity:out std_logic
);
end component;
component baudrate_generator
generic(full_plus_count:bd_count:=bd9600_fpc;
rise_plus_count:bd_count:=bd9600_hpc);
port(clk:in std_logic;
reset_n:in std_logic;
ce:in std_logic;
bdout:out std_logic;
indicator:out std_logic
);
end component;
component detector is
port(clk,reset_n,rxd:in std_logic;
new_data:out std_logic);
end component;
component swith_bus
generic (bus_width:integer:=8);
port(din1,din2:in std_logic_vector(bus_width-1 downto 0);
sel:in std_logic;
dout:out std_logic_vector(bus_width-1 downto 0));
end component;
component swith is
port(din1,din2:in std_logic;
sel:in std_logic;
dout:out std_logic);
end component;
component shift_register is
generic(total_bit:integer:=10);
port( clk:in std_logic;
reset_n:in std_logic;
din:in std_logic;
regs:out std_logic_vector(total_bit-1 downto 0);
dout:out std_logic);
end component;
component UART1 IS
GENERIC(DATA_BIT:INTEGER :=8;
TOTAL_BIT:INTEGER:=10;
PARITY_RULE:PARITY:=even);
PORT( clk,reset_n:in std_logic;
new_data:in std_logic;----信号监测与复位信号
reset_dt:out std_logic;
reset_part:out std_logic;
ce_part:out std_logic;
send_si:out std_logic;
sel_si :out std_logic;
regs:in std_logic_vector(TOTAL_BIT-1 downto 0);
sel_clk:out std_logic;
overflow:in std_logic;
sel_pv:out std_logic;
parity:in std_logic;
sel_out :out std_logic;
send:in std_logic;
send_bus:in std_logic_vector(DATA_BIT-1 DOWNTO 0);
send_over:out std_logic;
recv:out std_logic;
recv_bus:out std_logic_vector(DATA_BIT-1 DOWNTO 0);
error1:out std_logic);
end component;
component counter is
generic (max_count :integer:=10);
port(clk,reset_n:in std_logic;
ce:in std_logic;
overflow:out std_logic);
end component;
constant vcc_constant:std_logic:='1';
signal bg_clk:std_logic;
signal bg_out:std_logic;
signal ce_part:std_logic;
signal counter_clk:std_logic;
signal clk_inv:std_logic;
signal indicator:std_logic;
signal new_data:std_logic;
signal overflow:std_logic;
signal parity:std_logic;
signal reset_dt:std_logic;
signal reset_part:std_logic;
signal sel_clk:std_logic;
signal sel_pv:std_logic;
signal sel_out:std_logic;
signal sel_si:std_logic;
signal send_si:std_logic;
signal sr_in:std_logic;
signal sr_out:std_logic;
signal vcc:std_logic;
signal pv_source:std_logic_vector(data_bit-1 downto 0);
signal recv_parity_source:std_logic_vector(data_bit-1 downto 0);
signal regs:std_logic_vector(total_bit-1 downto 0);
signal send_parity_source:std_logic_vector(data_bit-1 downto 0);
begin
u_bg:baudrate_generator
port map(clk=>clk,
reset_n=>reset_part,
ce=>ce_part,
bdout=>bg_out,
indicator=> indicator
);
U_core:UART1
PORT MAP( clk=>clk,reset_n=>reset_n,
new_data=>new_data,----信号监测与复位信号
reset_dt=>reset_dt,
reset_part=>reset_part,
ce_part=>ce_part,
send_si=>send_si,
sel_si=>sel_si,
regs=>regs,
sel_clk=>sel_clk,
overflow=>overflow,
sel_pv=>sel_pv,
parity=>parity,
sel_out=>sel_out,
send=>send,
send_bus=>send_parity_source,
send_over=>send_over,
recv=>recv,
recv_bus=>recv_parity_source,
error1=>error1);
u_counter :counter
port map (clk=>counter_clk,
reset_n=>reset_part,
ce=>ce_part,
overflow=>overflow);
u_counterclkswith:swith
port map(din1=>indicator,
din2=>clk_inv,
sel=>sel_clk,
dout=>counter_clk);
u_detector:detector
port map(rxd=>rxd,
clk=>clk,
reset_n=>reset_dt,
new_data=>new_data);
u_parityverifier:parity_verifier
port map( parity=>parity,
source=>pv_source);
u_busswith:swith_bus
port map(din1=>send_parity_source(data_bit-1 downto 0),
din2=>recv_parity_source(data_bit-1 downto 0),
sel=>sel_pv,
dout=>pv_source(data_bit-1 downto 0));
u_siswith:swith
port map(din1=>send_si,
din2=>rxd,
sel=>sel_si,
dout=>sr_in);
u_sr:shift_register
port map(clk=>bg_clk,
din=>sr_in,
dout=>sr_out,
regs=>regs(total_bit-1 downto 0),
reset_n=>reset_part);
u_srclkswith:swith
port map(din1=>bg_out,
din2=>clk_inv,
sel=>sel_clk,
dout=>bg_clk);
u_txdswith:swith
port map(din1=>vcc,
din2=>sr_out,
sel=>sel_out,
dout=>txd);
end rtl;
波特率
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
package uart_1 is
type dt_state is(dt_unlock,dt_lock);
type bd_count is range 65535 downto 0;
constant bd9600_fpc:bd_count:=5208;
constant bd9600_hpc:bd_count:=2604;
constant bdtest_fpc:bd_count:=10;
constant bdtest_hpc:bd_count:=5;
type parity is(none,odd,even);
function multixor(din:in std_logic_vector) return std_logic;
end uart_1;
package body uart_1 is
function multixor(din:in std_logic_vector)return std_logic is
variable check:std_logic;
begin
check:=din(din'low);
for i in 1 to (din'high)loop
check:=check xor din(i);
end loop;
return check;
end multixor;
end uart_1;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.uart_1.all;
entity baudrate_generator is
generic(full_plus_count:bd_count:=bd9600_fpc;
rise_plus_count:bd_count:=bd9600_hpc);
port(clk:in std_logic;
reset_n:in std_logic;
ce:in std_logic;
bdout:out std_logic;
indicator:out std_logic
);
end baudrate_generator;
architecture rtl of baudrate_generator is
begin
process(clk,reset_n,ce)
variable clk_count:bd_count:=0;
begin
if reset_n='0' then clk_count:=0;
bdout<='0';indicator<='0';
elsif rising_edge(clk) then
if ce='1' then
if clk_count<full_plus_count-1 then
clk_count:=clk_count+1;
else clk_count:=0;
end if;
end if;
if (clk_count>rise_plus_count-1 and clk_count<=full_plus_count-1) then
bdout<='1'; else bdout<='0';
end if;
if clk_count=full_plus_count-1 then indicator<='1';
elsif clk_count=0 then indicator<='0';
end if;
end if;
end process;
end rtl;
计数器
library ieee;
use ieee.std_logic_1164.all;
entity counter is
generic (max_count :integer:=10);
port(clk,reset_n:in std_logic;
ce:in std_logic;
overflow:out std_logic);
end counter;
architecture rtl of counter is
begin
process(clk,ce,reset_n)
variable count:integer range 0 to 10;
begin
if reset_n='0' then
count:=0;overflow<='0';
elsif rising_edge(clk)then
if ce='1' then
if count="max"_count-1 then overflow<='1';count:=0;
else count:=count+1;overflow<='0';
end if;
end if;
end if;
end process;
end rtl;
信号监测
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity detector is
port(clk,reset_n,rxd:in std_logic;
new_data:out std_logic);
end detector;
architecture rtl of detector is
type dt_state is(dt_unlock,dt_lock);
signal state:dt_state;
begin
process(clk,reset_n,rxd)
begin
if reset_n='0' then
state<=dt_unlock;
new_data<='0';
elsif rising_edge(clk) then
if rxd='0' and state<=dt_unlock then
new_data<='1';
state<=dt_lock;
else new_data<='0';
end if;
end if;
end process;
end rtl;
奇偶校验
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.uart_1.all;
entity parity_verifier is
generic(data_length:integer:=8;
parity_rule:parity:=even);
port(
source:in std_logic_vector(data_length-1 downto 0);
parity:out std_logic
);
end parity_verifier;
architecture rtl of parity_verifier is
begin
with parity_rule select
parity<=multixor(source) when odd,
(not multixor(source)) when even,
'1' when others;
end rtl;
移位寄存器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.uart_1.all;
entity shift_register is
generic(total_bit:integer:=10);
port( clk:in std_logic;
reset_n:in std_logic;
din:in std_logic;
regs:out std_logic_vector(total_bit-1 downto 0);
dout:out std_logic);
end shift_register;
architecture rtl of shift_register is
signal shift_regs:std_logic_vector(total_bit-1 downto 0);
begin
regs<=shift_regs;
process(clk,reset_n,din)
begin
if reset_n='1' then dout<='1';
elsif rising_edge(clk) then dout<=shift_regs(total_bit-1);
shift_regs(total_bit-1 downto 1)<=shift_regs(total_bit-2 downto 0);
shift_regs(0)<=din;
end if;
end process;
end rtl;
总线选择
library ieee;
use ieee.std_logic_1164.all;
entity swith_bus is
generic (bus_width:integer:=8);
port(din1,din2:in std_logic_vector(bus_width-1 downto 0);
sel:in std_logic;
dout:out std_logic_vector(bus_width-1 downto 0));
end swith_bus;
architecture rtl of swith_bus is
begin
with sel select
dout<=din1 when '0',
din2 when others;
end rtl ;
二选一
library ieee;
use ieee.std_logic_1164.all;
entity swith is
port(din1,din2:in std_logic;
sel:in std_logic;
dout:out std_logic);
end swith;
architecture rtl of swith is
begin
with sel select
dout<=din1 when '0',
din2 when others;
end rtl ;
uart内核控制器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.uart_1.all;
ENTITY UART1 IS
GENERIC(DATA_BIT:INTEGER :=8;
TOTAL_BIT:INTEGER:=10;
PARITY_RULE:PARITY:=NONE);
PORT( clk,reset_n:in std_logic;
new_data:in std_logic;----信号监测与复位信号
reset_dt:out std_logic;
reset_part:out std_logic;
ce_part:out std_logic;
send_si:out std_logic;
sel_si :out std_logic;
regs:in std_logic_vector(TOTAL_BIT-1 downto 0);
sel_clk:out std_logic;
overflow:in std_logic;
sel_pv:out std_logic;
parity:in std_logic;
sel_out :out std_logic;
send:in std_logic;
send_bus:in std_logic_vector(DATA_BIT-1 DOWNTO 0);
send_over:out std_logic;
recv:out std_logic;
recv_bus:out std_logic_vector(DATA_BIT-1 DOWNTO 0);
error1:out std_logic);
end UART1;
ARCHITECTURE rtl of UART1 is
type uart_state is(uart_idle,uart_recv,uart_send,uart_load,uart_end_send,uart_end_recv);
signal state:uart_state:=uart_idle;
signal send_buf:std_logic_vector(TOTAL_BIT-1 downto 0);
signal si_count:integer range 0 to 15:=0;
begin
send_buffer:process(send_bus,parity)
begin
send_buf(0)<='0';
send_buf(DATA_BIT downto 1)<=send_bus(DATA_BIT-1 DOWNTO 0);
if PARITY_RULE=odd or PARITY_RULE=even then
send_buf(DATA_BIT+1)<=parity;
send_buf(TOTAL_BIT-1 downto DATA_BIT+2)<=(OTHERS=>'1');
ELSE send_buf(TOTAL_BIT-1 downto DATA_BIT+1)<=(OTHERS=>'1');
END IF;
END PROCESS;
si_swith:process(reset_n,si_count,send_buf)
begin
if reset_n='0' then
send_si<='1';
else send_si<=send_buf(si_count);
end if;
end process;
main:process(clk,reset_n)
begin
if reset_n='0' then
reset_dt<='1';--信号监测复位
reset_part<='0';
ce_part<='0';
sel_si<='0';
sel_clk<='0';
sel_pv<='0';
sel_out<='0';
send_over<='0';
recv<='0';
error1<='0';
state<=uart_idle;
si_count<=0;
elsif rising_edge(clk) then
case state is
when uart_idle=>
if new_data='1' then
reset_part<='0';
ce_part<='0';
sel_si<='1';
sel_clk<='0';
sel_out<='1';
sel_pv<='1';
state<=uart_recv;
elsif send='1' then
reset_part<='0';
ce_part<='0';
sel_si<='0';
sel_clk<='0';
sel_out<='0';
sel_pv<='0';
si_count<=TOTAL_BIT-1;
STATE<=uart_load;
else
reset_dt<='1';
end if;
when uart_load =>
if overflow='1' then
reset_part<='0';
ce_part<='0';
sel_si<='0';
sel_clk<='0';
sel_out<='0';
sel_pv<='0';
state<=uart_send;
else
sel_clk<='1';if not(si_count=TOTAL_BIT-1) THEN
si_count<=si_count+1;
else si_count<=0;
end if;
reset_part<='1';ce_part<='1';
end if;
when uart_send =>
if overflow='1' then
send_over<='1';
state<=uart_end_send;
else
reset_part<='1';
ce_part<='1';
end if;
when uart_end_send=>
ce_part<='0';
reset_dt<='0';
send_over<='0';
state<=uart_idle;
when uart_recv=>
if overflow='1' then
recv<='1';
state<=uart_end_recv;
else
reset_part<='1';
ce_part<='1';
end if;
when uart_end_recv=>
if not(regs(0)=parity) then
error1<='1';
end if;
ce_part<='0';
reset_dt<='0';
recv<='0';
state<=uart_idle;
when others=>error1<='1';
state<=uart_idle;
end case;
end if;
end process;
end rtl;
文章评论(0条评论)
登录后参与讨论