?? can_btl.vhd
字號(hào):
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
--use ieee.std_logic_arith.all;
entity can_btl is
port (
clk: in std_logic;
rst: in std_logic;
rx : in std_logic;
-- Mode register
reset_mode: in std_logic;
-- Bus Timing 0 register
baud_r_presc : in std_logic_vector(5 downto 0);
sync_jump_width : in std_logic_vector(1 downto 0);
-- Bus Timing 1 register
time_segment1 : in std_logic_vector(3 downto 0);
time_segment2 : in std_logic_vector(2 downto 0);
triple_sampling : in std_logic;
-- Output from can_bsp module
rx_idle : in std_logic;
transmitting : in std_logic;
last_bit_of_inter : in std_logic;
-- Output signals from this module
clk_en : out std_logic ;
sample_point : out std_logic ;
sampled_bit : out std_logic ;
sampled_bit_q : out std_logic ;
tx_point : out std_logic ;
hard_sync : out std_logic ;
resync : out std_logic);
end can_btl;
architecture RTL of can_btl is
constant Tp : time := 1 ns;
signal clk_cnt : std_logic_vector(8 downto 0);
signal clk_en_reg : std_logic;
signal sync_blocked : std_logic;
signal resync_blocked : std_logic;
signal sampled_bit_reg : std_logic;
signal resync_reg : std_logic;
signal hard_sync_reg : std_logic;
signal quant_cnt : std_logic_vector(7 downto 0);
signal delay : std_logic_vector(3 downto 0);
signal sync : std_logic;
signal seg1 : std_logic;
signal seg2 : std_logic;
signal resync_latched : std_logic;
signal sample : std_logic_vector(1 downto 0);
signal go_sync : std_logic;
signal go_seg1 : std_logic;
signal go_seg2 : std_logic;
signal preset_cnt : std_logic_vector(8 downto 0);
signal sync_window : std_logic;
signal baud_r_presc_plus_1: std_logic_vector(5 downto 0);
signal delay_temp : unsigned(3 downto 0);
begin
clk_en <= clk_en_reg;
resync <= resync_reg;
hard_sync <= hard_sync_reg;
sampled_bit <= sampled_bit_reg;
baud_r_presc_plus_1 <= baud_r_presc + 1;
preset_cnt <= "00"&baud_r_presc_plus_1(5 downto 0)&'0'; -- (BRP+1)*2
hard_sync_reg <= '1' when (rx_idle = '1' or last_bit_of_inter = '1') and rx = '0' and sampled_bit_reg = '1' and sync_blocked = '1' and transmitting = '0' else '0'; -- Hard synchronization
resync_reg <= '1' when rx_idle = '0' and rx = '0' and sampled_bit_reg = '1' and sync_blocked = '0' and resync_blocked = '0' and transmitting = '0' else '0'; -- Re-synchronization
-- Generating general enable signal that defines baud rate.
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
clk_cnt <= (others => '0');
elsif ((clk_cnt = (preset_cnt-1)) or reset_mode = '1') then
clk_cnt <= (others => '0') after Tp;
else
clk_cnt <= clk_cnt + 1 after Tp;
end if;
end if;
end process;
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
clk_en_reg <= '0';
elsif (clk_cnt = (preset_cnt-1)) then
clk_en_reg <= '1' after Tp;
else
clk_en_reg <= '0' after Tp;
end if;
end if;
end process;
-- Changing states
go_sync <= '1' when clk_en_reg = '1' and (seg2 = '1' and hard_sync_reg = '0' and resync_reg = '0' and (quant_cnt = time_segment2)) else '0';
go_seg1 <= '1' when clk_en_reg = '1' and (sync = '1' or hard_sync_reg = '1' or (resync_reg = '1' and seg2 = '1' and sync_window = '1') or (resync_latched = '1' and sync_window = '1')) else '0';
go_seg2 <= '1' when clk_en_reg = '1' and (seg1 = '1' and hard_sync_reg = '0' and (quant_cnt = (time_segment1 + delay))) else '0';
-- When early edge is detected outside of the SJW field, synchronization request is latched and performed when
-- SJW is reached
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
resync_latched <= '0';
elsif (resync_reg = '1' and seg2 = '1' and sync_window = '0') then
resync_latched <= '1' after Tp;
elsif (go_seg1 = '1') then
resync_latched <= '0';
end if;
end if;
end process;
-- Synchronization stage/segment
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
sync <= '0';
elsif (go_sync = '1') then
sync <= '1' after Tp;
elsif (go_seg1 = '1') then
sync <= '0' after Tp;
end if;
end if;
end process;
tx_point <= go_sync;
-- Seg1 stage/segment (together with propagation segment which is 1 quant long)
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
seg1 <= '1';
elsif (go_seg1 = '1') then
seg1 <= '1' after Tp;
elsif (go_seg2 = '1') then
seg1 <= '0' after Tp;
end if;
end if;
end process;
-- Seg2 stage/segment
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
seg2 <= '0';
elsif (go_seg2 = '1') then
seg2 <= '1' after Tp;
elsif (go_sync = '1' or go_seg1 = '1') then
seg2 <= '0' after Tp;
end if;
end if;
end process;
-- Quant counter
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
quant_cnt <= (others =>'0');
elsif (go_sync = '1' or go_seg1 = '1' or go_seg2 = '1' or reset_mode = '1') then
quant_cnt <= (others =>'0') after Tp;
elsif (clk_en_reg = '1') then
quant_cnt <= quant_cnt + 1 after Tp;
end if;
end if;
end process;
-- When late edge is detected (in seg1 stage), stage seg1 is prolonged.
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
delay_temp <= (others =>'0');
elsif (clk_en_reg = '1' and resync_reg = '1' and seg1 = '1') then
if (quant_cnt > sync_jump_width) then
delay_temp <= to_unsigned(conv_integer(sync_jump_width),4) + 1 after
Tp;
else
delay_temp <= to_unsigned(conv_integer(quant_cnt),4) + 1 after Tp;
end if;
elsif (go_sync = '1' or go_seg1 = '1') then
delay_temp <= (others =>'0');
end if;
end if;
delay <= std_logic_vector(delay_temp);
end process;
-- If early edge appears within this window (in seg2 stage), phase error is fully compensated
sync_window <= '1' when((time_segment2 - quant_cnt) < ( sync_jump_width + 1)) else '0';
-- Sampling data (memorizing two samples all the time).
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
sample <= "11";
elsif (clk_en_reg = '1') then
sample <= sample(0)℞
end if;
end if;
end process;
-- When enabled, tripple sampling is done here.
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
sampled_bit_reg <= '1';
sampled_bit_q <= '1';
sample_point <= '0';
elsif (clk_en_reg = '1' and hard_sync_reg = '0' ) then
if (seg1 = '1' and (quant_cnt = (time_segment1 + delay))) then
sample_point <= '1' after Tp;
sampled_bit_q <= sampled_bit_reg after Tp;
if (triple_sampling = '1') then
sampled_bit_reg <= (sample(0) and sample(1)) or ( sample(0) and rx) or (sample(1) and rx);
else
sampled_bit_reg <= rx after Tp;
end if;
else
sample_point <= '0' after Tp;
end if;
end if;
end if;
end process;
-- Blocking synchronization (can occur only once in a bit time)
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
sync_blocked <= '0' after Tp;
elsif (clk_en_reg = '1') then
if (hard_sync_reg = '1' or resync_reg = '1') then
sync_blocked <= '1' after Tp;
elsif (seg2 = '1' and (quant_cnt = time_segment2)) then
sync_blocked <= '0' after Tp;
end if;
end if;
end if;
end process;
-- Blocking resynchronization until reception starts (needed because after reset mode exits we are waiting for
-- end-of-frame and interframe. No resynchronization is needed meanwhile). */
process(clk,rst)
begin
if (clk = '1' and clk'event) then
if (rst = '1') then
resync_blocked <= '1' after Tp;
elsif (reset_mode = '1') then
resync_blocked <= '1' after Tp;
elsif (hard_sync_reg = '1') then
resync_blocked <= '0' after Tp;
end if;
end if;
end process;
end RTL;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -