URL
https://opencores.org/ocsvn/uart_fpga_slow_control_migrated/uart_fpga_slow_control_migrated/trunk
Subversion Repositories uart_fpga_slow_control_migrated
Compare Revisions
- This comparison shows the changes necessary to convert path
/uart_fpga_slow_control/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/ab_top.vhd
0,0 → 1,305
-- |
-- unit name: ab_top (Register map access) |
-- |
-- author: Andrea Borga (andrea.borga@nikhef.nl) |
-- |
-- |
-- date: $26/08/2011 $: created |
-- |
-- version: $Rev 0 $: |
-- |
-- description: |
-- NOTE: look through the code for this |
-- |
-- -- ##################### |
-- -- ##################### |
-- |
-- to spot where the code needs customization |
-- |
-- dependencies: |
-- gh_uart_16550 |
-- ab_uart_lbus_slave |
-- ab_uart_16550_wrapper |
-- ab_register_rx_handler |
-- ab_register_tx_handler |
-- |
-- references: <reference one> |
-- <reference two> ... |
-- |
-- modified by: $Author:: $: |
-- |
-- |
-- |
------------------------------------------------------------------------------- |
-- last changes: <date> <initials> <log> |
-- <extended description> |
------------------------------------------------------------------------------- |
-- TODO: |
-- |
-- |
-- |
------------------------------------------------------------------------------- |
|
--============================================================================= |
-- Libraries |
--============================================================================= |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
--============================================================================= |
-- Entity declaration for ab_top |
--============================================================================= |
|
entity ab_top is |
port( |
clk_uart_29MHz_i : in std_logic; |
clk_uart_monitor_o : out std_logic; |
-- ##################### |
-- ADD your registers toward the rest of the logic here |
-- ##################### |
uart_din_o : out std_logic; |
uart_dout_i : in std_logic); |
|
end ab_top; |
|
|
--============================================================================= |
-- architecture declaration |
--============================================================================= |
|
architecture a0 of ab_top is |
|
component uart_16550_wrapper |
port( |
-- general purpose |
sys_clk_i : in std_logic; -- system clock |
sys_rst_i : in std_logic; -- system reset |
-- TX/RX process command line |
echo_en_i : in std_logic; -- Echo enable (byte by byte) enable/disable = 1/0 |
tx_addr_wwo_i : in std_logic; -- control of TX process With or WithOut address W/WO=(1/0) |
-- serial I/O side |
lantronix_output_i : in std_logic; -- Lantronix Serial data OUTPUT signal |
lantronix_input_o : out std_logic; -- Lantronix Serial data INPUT signal |
cp_b : inout std_logic_vector(2 downto 0); -- general purpose IO pins |
-- parallel I/O side |
s_br_clk_uart_o : out std_logic; -- br_clk clock probe signal |
-- RX part/control |
v_rx_add_o : out std_logic_vector(15 downto 0); -- 16 bits full addr ram input |
v_rx_data_o : out std_logic_vector(31 downto 0); -- 32 bits full data ram input |
s_rx_rdy_o : out std_logic; -- add/data ready to be write into RAM |
s_rx_stb_read_data_i : in std_logic; -- strobe signal from RAM ... |
-- TX part/control |
s_tx_proc_rqst_i : in std_logic; -- stream TX process request 1/0 tx enable/disable |
v_tx_add_ram_i : in std_logic_vector(15 downto 0); -- 16 bits full addr ram output |
v_tx_data_ram_i : in std_logic_vector(31 downto 0); -- 32 bits full data ram output |
s_tx_ram_data_rdy_i : in std_logic; -- ram output data ready and stable |
s_tx_stb_ram_data_acq_o : out std_logic -- strobe ram data/address output acquired 1/0 acquired/not acquired |
); |
end component; |
|
-- |
-- Internal signal declaration |
-- |
|
-- generic signals |
signal s_rst : std_logic; -- main reset |
signal s_clk_uart : std_logic; -- slow (29 MHz) clock |
|
-- uart control signals |
signal s_uart_cp : std_logic_vector (2 downto 0); -- unused |
signal s_uart_br_clk : std_logic; -- unused clock monitor |
signal s_uart_rx_add : std_logic_vector (15 downto 0); |
signal s_uart_rx_data : std_logic_vector (31 downto 0); |
signal s_uart_rx_rdy : std_logic; |
signal s_uart_rx_stb_read_data : std_logic; |
signal s_update : std_logic; |
signal s_uart_tx_add : std_logic_vector (15 downto 0); |
signal s_uart_tx_data : std_logic_vector (31 downto 0); |
signal s_uart_tx_data_rdy : std_logic; |
signal s_uart_tx_req : std_logic; |
signal s_uart_tx_stb_acq : std_logic; |
signal s_tx_complete : std_logic; |
|
|
-- address decoder signals |
|
signal r_config_addr_uart : std_logic_vector (1 downto 0); |
signal r_open : std_logic_vector (31 downto 0); |
signal r_leds : std_logic_vector (7 downto 0); |
signal r_test_reg01 : std_logic_vector (31 downto 0); |
signal r_test_reg02 : std_logic_vector (31 downto 0); |
signal r_test_reg03 : std_logic_vector (31 downto 0); |
signal r_test_reg04 : std_logic_vector (31 downto 0); |
signal r_test_reg05 : std_logic_vector (31 downto 0); |
-- ##################### |
-- declare your registers here |
-- ##################### |
|
-- |
-- State Machine states |
-- |
|
type t_tx_reg_map is (IDLE, WAIT_A_BYTE, LATCH, TRANSMIT); |
signal s_tx_fsm : t_tx_reg_map; |
|
begin |
|
s_rst <= not uart_rst_i; |
|
uart_leds_o <= r_leds; -- Let there be light ... |
|
-- UART simple register map |
register_map : process (s_rst, s_clk_uart) |
begin |
if s_rst = '1' then -- reset all registers here |
s_uart_rx_stb_read_data <= '0'; |
s_update <= '0'; |
r_leds <= (others => '0'); |
r_config_addr_uart <= "10"; |
r_test_reg01 <= (others => '0'); |
r_test_reg02 <= (others => '0'); |
r_test_reg03 <= (others => '0'); |
r_test_reg04 <= (others => '0'); |
r_test_reg05 <= (others => '0'); |
-- ##################### |
-- reset your registers here |
-- ##################### |
elsif rising_edge(s_clk_uart) then |
if s_uart_rx_rdy = '1' then |
case (s_uart_rx_add) is |
when X"0020" => r_leds <= s_uart_rx_data(7 downto 0); |
-- ##################### |
-- declare more registers here to WRITE |
-- ##################### |
when X"0030" => r_test_reg03 <= s_uart_rx_data; |
when X"0031" => r_test_reg04 <= s_uart_rx_data; |
when X"0032" => r_test_reg05 <= s_uart_rx_data; |
when X"0040" => r_test_reg01 <= s_uart_rx_data; |
when X"0050" => r_test_reg02 <= s_uart_rx_data; |
when X"8000" => s_update <= '1'; -- register update self clearing |
when others => r_open <= s_uart_rx_data; |
end case; |
s_uart_rx_stb_read_data <= '1'; |
else |
s_uart_rx_stb_read_data <= '0'; |
s_update <= '0'; |
end if; |
end if; |
end process; |
|
register_update : process (s_rst, s_clk_uart) |
variable v_uart_tx_add : unsigned (15 downto 0); |
variable v_count : unsigned (15 downto 0); |
begin |
if s_rst = '1' then -- reset all registers here |
s_uart_tx_data_rdy <= '0'; |
s_uart_tx_req <= '0'; |
v_uart_tx_add := (others => '0'); |
v_count := (others => '0'); |
s_uart_tx_data <= (others => '0'); |
s_uart_tx_add <= (others => '0'); |
-- ##################### |
-- reset your registers here |
-- ##################### |
s_tx_fsm <= IDLE; |
elsif rising_edge(s_clk_uart) then |
case s_tx_fsm is |
when IDLE => |
if s_update = '1' then |
s_tx_fsm <= WAIT_A_BYTE; |
else |
s_tx_fsm <= IDLE; |
s_uart_tx_data_rdy <= '0'; |
s_uart_tx_req <= '0'; |
v_uart_tx_add := (others => '0'); |
v_count := (others => '0'); |
s_uart_tx_data <= (others => '0'); |
s_uart_tx_add <= (others => '0'); |
end if; |
when WAIT_A_BYTE => |
s_uart_tx_data_rdy <= '0'; |
v_count := v_count + 1; |
if v_count = X"0900" then |
v_uart_tx_add := v_uart_tx_add + 1; |
s_tx_fsm <= LATCH; |
else |
s_tx_fsm <= WAIT_A_BYTE; |
end if; |
when LATCH => |
if s_uart_tx_stb_acq = '0' then |
s_uart_tx_req <= '1'; |
s_uart_tx_add <= std_logic_vector (v_uart_tx_add); |
case v_uart_tx_add is |
when X"0001" => s_uart_tx_data <= (others => '0'); -- reserved synch register |
s_tx_fsm <= TRANSMIT; |
-- ##################### |
-- declare more registers here to READ |
-- ##################### |
when X"0010" => s_uart_tx_data <= (others => '0'); |
s_tx_fsm <= TRANSMIT; |
when X"0011" => s_uart_tx_data <= (others => '0'); |
s_tx_fsm <= TRANSMIT; |
when X"0020" => s_uart_tx_data (7 downto 0) <= r_leds; |
s_tx_fsm <= TRANSMIT; |
when X"0030" => s_uart_tx_data <= r_test_reg03; |
s_tx_fsm <= TRANSMIT; |
when X"0031" => s_uart_tx_data <= r_test_reg04; |
s_tx_fsm <= TRANSMIT; |
when X"0032" => s_uart_tx_data <= r_test_reg05; |
s_tx_fsm <= TRANSMIT; |
when X"0040" => s_uart_tx_data <= r_test_reg01; |
s_tx_fsm <= TRANSMIT; |
when X"0050" => s_uart_tx_data <= r_test_reg02; |
s_tx_fsm <= TRANSMIT; |
-- End Of Transmission register = last register + 1 |
when X"0051" => s_tx_fsm <= IDLE; -- end of transmission |
when others => s_uart_tx_data <= (others => '0'); |
v_uart_tx_add := v_uart_tx_add + 1; |
s_uart_tx_data_rdy <= '0'; |
s_tx_fsm <= LATCH; |
end case; |
else |
v_count := (others => '0'); |
s_tx_fsm <= WAIT_A_BYTE; |
end if; |
when TRANSMIT => |
s_uart_tx_data_rdy <= '1'; |
v_count := (others => '0'); |
s_tx_fsm <= WAIT_A_BYTE; |
when others => |
s_tx_fsm <= IDLE; |
end case; |
end if; |
end process; |
|
|
s_clk_uart <= clk_uart_29MHz_i; -- UART system clock 29.4912 MHz |
clk_uart_monitor_o <= s_uart_br_clk; |
|
uart_wrapper : uart_16550_wrapper |
port map( |
sys_clk_i => s_clk_uart, |
sys_rst_i => s_rst, |
echo_en_i => r_config_addr_uart(0), |
tx_addr_wwo_i => r_config_addr_uart(1), |
lantronix_output_i => uart_dout_i, |
lantronix_input_o => uart_din_o, |
cp_b => s_uart_cp, |
s_br_clk_uart_o => s_uart_br_clk, |
v_rx_add_o => s_uart_rx_add, |
v_rx_data_o => s_uart_rx_data, |
s_rx_rdy_o => s_uart_rx_rdy, |
s_rx_stb_read_data_i => s_uart_rx_stb_read_data, |
s_tx_proc_rqst_i => s_uart_tx_req, |
v_tx_add_ram_i => s_uart_tx_add, |
v_tx_data_ram_i => s_uart_tx_data, |
s_tx_ram_data_rdy_i => s_uart_tx_data_rdy, |
s_tx_stb_ram_data_acq_o => s_uart_tx_stb_acq |
); |
|
end architecture a0 ; -- of UART_control |
|
/library/gh_counter_down_ce_ld_tc.vhd
0,0 → 1,96
----------------------------------------------------------------------------- |
-- Filename: gh_Counter_down_ce_ld_tc.vhd |
-- |
-- Description: |
-- Binary up/down counter with load, count enable and TC |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 09/03/05 S A Dodd Initial revision |
-- 2.0 09/17/05 h lefevre name change to avoid conflict |
-- with other libraries |
-- 2.1 09/24/05 S A Dodd fix description |
-- 2.2 05/21/06 S A Dodd fix typo's |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
USE ieee.std_logic_unsigned.all; |
USE ieee.std_logic_arith.all; |
|
ENTITY gh_counter_down_ce_ld_tc IS |
GENERIC (size: INTEGER :=8); |
PORT( |
CLK : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : IN STD_LOGIC; |
CE : IN STD_LOGIC; |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
TC : OUT STD_LOGIC |
); |
END gh_counter_down_ce_ld_tc; |
|
ARCHITECTURE a OF gh_counter_down_ce_ld_tc IS |
|
signal iQ : STD_LOGIC_VECTOR (size-1 DOWNTO 0); |
signal iTC : STD_LOGIC; |
|
BEGIN |
|
-- |
-- outputs |
|
TC <= (iTC and CE); |
|
Q <= iQ; |
|
---------------------------------- |
---------------------------------- |
|
PROCESS (CLK,rst) |
BEGIN |
if (rst = '1') then |
iTC <= '0'; |
elsif (rising_edge(CLK)) then |
if (LOAD = '1') then |
if (D = x"0") then |
iTC <= '1'; |
else |
iTC <= '0'; |
end if; |
elsif (CE = '0') then -- LOAD = '0' |
if (iQ = x"0") then |
iTC <= '1'; |
else |
iTC <= '0'; |
end if; |
else -- (CE = '1') |
if (iQ = x"1") then |
iTC <= '1'; |
else |
iTC <= '0'; |
end if; |
end if; |
end if; |
END PROCESS; |
|
|
PROCESS (CLK,rst) |
BEGIN |
if (rst = '1') then |
iQ <= (others => '0'); |
elsif (rising_edge(CLK)) then |
if (LOAD = '1') then |
iQ <= D; |
elsif (CE = '1') then |
iQ <= (iQ - "01"); |
end if; |
end if; |
END PROCESS; |
|
END a; |
/library/gh_counter_integer_down.vhd
0,0 → 1,58
----------------------------------------------------------------------------- |
-- Filename: gh_counter_integer_down.vhd |
-- |
-- Description: |
-- an integer down counter |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 10/15/05 G Huber Initial revision |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
ENTITY gh_counter_integer_down IS |
generic(max_count : integer := 8); |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : in STD_LOGIC; -- load D |
CE : IN STD_LOGIC; -- count enable |
D : in integer RANGE 0 TO max_count; |
Q : out integer RANGE 0 TO max_count |
); |
END gh_counter_integer_down; |
|
ARCHITECTURE a OF gh_counter_integer_down IS |
|
signal iQ : integer RANGE 0 TO max_count; |
|
BEGIN |
|
Q <= iQ; |
|
process (clk,rst) |
begin |
if (rst = '1') then |
iQ <= 0; |
elsif (rising_edge(clk)) then |
if (LOAD = '1') then |
iQ <= D; |
elsif (CE = '1') then |
if (iQ = 0) then |
iQ <= max_count; |
else |
iQ <= iQ - 1; |
end if; |
end if; |
end if; |
end process; |
|
END a; |
|
/library/gh_shift_reg_PL_sl.vhd
0,0 → 1,60
----------------------------------------------------------------------------- |
-- Filename: gh_shift_reg_PL_sl.vhd |
-- |
-- Description: |
-- a shift register with Parallel Load |
-- will shift left (MSB to LSB) |
-- |
-- Copyright (c) 2006 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 02/11/06 G Huber Initial revision |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
|
ENTITY gh_shift_reg_PL_sl IS |
GENERIC (size: INTEGER := 16); |
PORT( |
clk : IN STD_logic; |
rst : IN STD_logic; |
LOAD : IN STD_LOGIC; -- load data |
SE : IN STD_LOGIC; -- shift enable |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END entity; |
|
ARCHITECTURE a OF gh_shift_reg_PL_sl IS |
|
signal iQ : STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
|
BEGIN |
|
Q <= iQ; |
|
|
process(clk,rst) |
begin |
if (rst = '1') then |
iQ <= (others => '0'); |
elsif (rising_edge(clk)) then |
if (LOAD = '1') then |
iQ <= D; |
elsif (SE = '1') then -- shift left |
iQ(size-1 downto 0) <= '0' & iQ(size-1 downto 1); |
else |
iQ <= iQ; |
end if; |
end if; |
end process; |
|
|
END a; |
|
/library/gh_binary2gray.vhd
0,0 → 1,41
----------------------------------------------------------------------------- |
-- Filename: gh_binary2gray.vhd |
-- |
-- Description: |
-- a binary to gray code converter |
-- |
-- Copyright (c) 2006 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 12/26/06 G Huber Initial revision |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
ENTITY gh_binary2gray IS |
GENERIC (size: INTEGER := 8); |
PORT( |
B : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); -- binary value in |
G : out STD_LOGIC_VECTOR(size-1 DOWNTO 0) -- gray code out |
); |
END entity; |
|
ARCHITECTURE a OF gh_binary2gray IS |
|
BEGIN |
|
process (B) is |
begin |
for j in 0 to size-2 loop |
G(j) <= B(j) xor B(j+1); |
end loop; |
G(size-1) <= B(size-1); |
end process; |
|
END a; |
|
/library/gh_gray2binary.vhd
0,0 → 1,45
----------------------------------------------------------------------------- |
-- Filename: gh_gray2binary.vhd |
-- |
-- Description: |
-- a gray code to binary converter |
-- |
-- Copyright (c) 2006 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 12/26/06 G Huber Initial revision |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
ENTITY gh_gray2binary IS |
GENERIC (size: INTEGER := 8); |
PORT( |
G : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); -- gray code in |
B : out STD_LOGIC_VECTOR(size-1 DOWNTO 0) -- binary value out |
); |
END entity; |
|
ARCHITECTURE a OF gh_gray2binary IS |
|
signal iB : STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
|
BEGIN |
|
B <= iB; |
|
process (G,iB) is |
begin |
for j in 0 to size-2 loop |
iB(j) <= G(j) xor iB(j+1); |
end loop; |
iB(size-1) <= G(size-1); |
end process; |
|
END a; |
|
/library/gh_register_ce.vhd
0,0 → 1,50
----------------------------------------------------------------------------- |
-- Filename: gh_register_ce.vhd |
-- |
-- Description: |
-- register with clock enable |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 09/03/05 G Huber Initial revision |
-- 2.0 09/17/05 h lefevre name change to avoid conflict |
-- with other librarys |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
ENTITY gh_register_ce IS |
GENERIC (size: INTEGER := 8); |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
CE : IN STD_LOGIC; -- clock enable |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END gh_register_ce; |
|
ARCHITECTURE a OF gh_register_ce IS |
|
|
BEGIN |
|
PROCESS (clk,rst) |
BEGIN |
if (rst = '1') then |
Q <= (others =>'0'); |
elsif (rising_edge (clk)) then |
if (CE = '1') then |
Q <= D; |
end if; |
end if; |
END PROCESS; |
|
END a; |
|
/library/gh_counter_down_ce_ld.vhd
0,0 → 1,55
----------------------------------------------------------------------------- |
-- Filename: gh_Counter_down_ce_ld.vhd |
-- |
-- Description: |
-- Binary up/down counter with load, and count enable |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 09/24/05 S A Dodd Initial revision |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
USE ieee.std_logic_unsigned.all; |
USE ieee.std_logic_arith.all; |
|
ENTITY gh_counter_down_ce_ld IS |
GENERIC (size: INTEGER :=8); |
PORT( |
CLK : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : IN STD_LOGIC; |
CE : IN STD_LOGIC; |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END gh_counter_down_ce_ld; |
|
ARCHITECTURE a OF gh_counter_down_ce_ld IS |
|
signal iQ : STD_LOGIC_VECTOR (size-1 DOWNTO 0); |
|
BEGIN |
|
Q <= iQ; |
|
PROCESS (CLK,rst) |
BEGIN |
if (rst = '1') then |
iQ <= (others => '0'); |
elsif (rising_edge(CLK)) then |
if (LOAD = '1') then |
iQ <= D; |
elsif (CE = '1') then |
iQ <= (iQ - "01"); |
end if; |
end if; |
END PROCESS; |
|
END a; |
/library/gh_edge_det_XCD.vhd
0,0 → 1,94
----------------------------------------------------------------------------- |
-- Filename: gh_edge_det_XCD.vhd |
-- |
-- Description: |
-- an edge detector, for crossing clock domains - |
-- finds the rising edge and falling edge for a pulse crossing clock domains |
-- |
-- Copyright (c) 2006, 2008 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 09/16/06 S A Dodd Initial revision |
-- 2.0 04/12/08 hlefevre mod to double register between clocks |
-- output time remains the same |
-- |
----------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
|
entity gh_edge_det_XCD is |
port( |
iclk : in STD_LOGIC; -- clock for input data signal |
oclk : in STD_LOGIC; -- clock for output data pulse |
rst : in STD_LOGIC; |
D : in STD_LOGIC; |
re : out STD_LOGIC; -- rising edge |
fe : out STD_LOGIC -- falling edge |
); |
end entity; |
|
|
architecture a of gh_edge_det_XCD is |
|
signal iQ : std_logic; |
signal jkR, jkF : std_logic; |
signal irQ0, rQ0, rQ1 : std_logic; |
signal ifQ0, fQ0, fQ1 : std_logic; |
|
begin |
|
process(iclk,rst) |
begin |
if (rst = '1') then |
iQ <= '0'; |
jkR <= '0'; |
jkF <= '0'; |
elsif (rising_edge(iclk)) then |
iQ <= D; |
if ((D = '1') and (iQ = '0')) then |
jkR <= '1'; |
elsif (rQ1 = '1') then |
jkR <= '0'; |
else |
jkR <= jkR; |
end if; |
if ((D = '0') and (iQ = '1')) then |
jkF <= '1'; |
elsif (fQ1 = '1') then |
jkF <= '0'; |
else |
jkF <= jkF; |
end if; |
end if; |
end process; |
|
re <= (not rQ1) and rQ0; |
fe <= (not fQ1) and fQ0; |
|
process(oclk,rst) |
begin |
if (rst = '1') then |
irQ0 <= '0'; |
rQ0 <= '0'; |
rQ1 <= '0'; |
--------------- |
ifQ0 <= '0'; |
fQ0 <= '0'; |
fQ1 <= '0'; |
elsif (rising_edge(oclk)) then |
irQ0 <= jkR; |
rQ0 <= irQ0; |
rQ1 <= rQ0; |
--------------- |
ifQ0 <= jkF; |
fQ0 <= ifQ0; |
fQ1 <= fQ0; |
end if; |
end process; |
|
|
end a; |
/library/gh_Pulse_Generator.vhd
0,0 → 1,109
----------------------------------------------------------------------------- |
-- Filename: gh_Pulse_Generator.vhd |
-- |
-- Description: |
-- A Pulse Generator |
-- |
-- Copyright (c) 2005, 2006 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 09/24/05 S A Dodd Initial revision |
-- 1.1 02/18/06 G Huber add gh_ to name |
-- 1.2 03/09/06 S A Dodd fix typo's, add Period reload |
-- if Period_count > Period |
-- |
----------------------------------------------------------------------------- |
|
library IEEE; |
USE ieee.std_logic_1164.all; |
USE ieee.std_logic_unsigned.all; |
USE ieee.std_logic_arith.all; |
|
entity gh_Pulse_Generator is |
GENERIC(size_Period: INTEGER := 16); |
port( |
clk : in std_logic; |
rst : in std_logic; |
Period : in std_logic_vector (size_Period-1 downto 0); |
Pulse_Width : in std_logic_vector (size_Period-1 downto 0); |
ENABLE : in std_logic; |
Pulse : out std_logic |
); |
end entity; |
|
architecture a of gh_Pulse_Generator is |
|
COMPONENT gh_counter_down_ce_ld is |
GENERIC (size: INTEGER :=8); |
PORT( |
CLK : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : IN STD_LOGIC; |
CE : IN STD_LOGIC; |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END COMPONENT; |
|
signal trigger : std_logic; |
signal LD_Period : std_logic; |
signal Period_Count : std_logic_vector(size_Period-1 downto 0); |
signal Width_Count : std_logic_vector(size_Period-1 downto 0); |
signal Period_cmp : std_logic_vector(size_Period-1 downto 0); |
signal Width_cmp : std_logic_vector(size_Period-1 downto 0); |
|
signal LD_width : std_logic; |
signal E_width : std_logic; |
|
begin |
|
-- constant compare values ----------------------------------- |
Period_cmp(size_Period-1 downto 1) <= (others =>'0'); |
Period_cmp(0) <= '1'; |
Width_cmp <= (others => '0'); |
--------------------------------------------------------------- |
|
|
U1 : gh_counter_down_ce_ld |
Generic Map(size_Period) |
PORT MAP( |
clk => clk, |
rst => rst, |
LOAD => LD_Period, |
CE => ENABLE, |
D => Period, |
Q => Period_Count |
); |
|
LD_Period <= trigger or (not ENABLE); |
|
trigger <= '1' when (Period_Count > Period) else |
'1' when (Period_Count = Period_cmp) else |
'0'; |
|
----------------------------------------------------------- |
|
U2 : gh_counter_down_ce_ld |
Generic Map(size_Period) |
PORT MAP( |
clk => clk, |
rst => rst, |
LOAD => LD_width, |
CE => E_width, |
D => Pulse_Width, |
Q => Width_Count |
); |
|
LD_width <= trigger; |
|
E_width <= '0' when (Width_Count = Width_cmp) else |
'1'; |
|
Pulse <= E_width; |
|
end a; |
|
/library/gh_baud_rate_gen.vhd
0,0 → 1,160
----------------------------------------------------------------------------- |
-- Filename: gh_baud_rate_gen.vhd |
-- |
-- Description: |
-- a 16 bit baud rate generator |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 01/28/06 H LeFevre Initial revision |
-- 2.0 02/04/06 H LeFevre reload counter with register load |
-- 2.1 04/10/06 H LeFevre Fix error in rCLK |
-- |
----------------------------------------------------------------------------- |
library ieee ; |
use ieee.std_logic_1164.all ; |
use ieee.std_logic_arith.all ; |
use ieee.std_logic_unsigned.all ; |
|
entity gh_baud_rate_gen is |
port( |
clk : in std_logic; |
BR_clk : in std_logic; |
rst : in std_logic; |
WR : in std_logic; |
BE : in std_logic_vector (1 downto 0); -- byte enable |
D : in std_logic_vector (15 downto 0); |
RD : out std_logic_vector (15 downto 0); |
rCE : out std_logic; |
rCLK : out std_logic |
); |
end entity; |
|
architecture a of gh_baud_rate_gen is |
|
COMPONENT gh_register_ce is |
GENERIC (size: INTEGER := 8); |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
CE : IN STD_LOGIC; -- clock enable |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END COMPONENT; |
|
COMPONENT gh_counter_down_ce_ld is |
GENERIC (size: INTEGER :=8); |
PORT( |
CLK : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : IN STD_LOGIC; |
CE : IN STD_LOGIC; |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END COMPONENT; |
|
signal UB_LD : std_logic; |
signal LB_LD : std_logic; |
signal rate : std_logic_vector(15 downto 0); |
signal C_LD : std_logic; |
signal C_CE : std_logic; |
signal irLD : std_logic; -- added 02/04/06 |
signal rLD : std_logic; -- added 02/04/06 |
signal count : std_logic_vector(15 downto 0); |
|
begin |
|
rCE <= '1' when (count = x"01") else |
'0'; |
|
process(BR_clk,rst) |
begin |
if (rst = '1') then |
rCLK <= '0'; |
rLD <= '0'; |
elsif (rising_edge(BR_CLK)) then |
rLD <= irLD; |
if (count > ('0' & (rate(15 downto 1)))) then -- fixed 04/10/06 |
rCLK <= '1'; |
else |
rCLK <= '0'; |
end if; |
end if; |
end process; |
|
RD <= rate; |
|
---------------------------------------------- |
---------------------------------------------- |
|
UB_LD <= '0' when (WR = '0') else |
'0' when (BE(1) = '0') else |
'1'; |
|
u1 : gh_register_ce |
generic map (8) |
port map( |
clk => clk, |
rst => rst, |
ce => UB_LD, |
D => d(15 downto 8), |
Q => rate(15 downto 8) |
); |
|
LB_LD <= '0' when (WR = '0') else |
'0' when (BE(0) = '0') else |
'1'; |
|
u2 : gh_register_ce |
generic map (8) |
port map( |
clk => clk, |
rst => rst, |
ce => LB_LD, |
D => d(7 downto 0), |
Q => rate(7 downto 0) |
); |
|
------------------------------------------------------------ |
------------ baud rate counter ----------------------------- |
------------------------------------------------------------ |
|
process(clk,rst) |
begin |
if (rst = '1') then |
irLD <= '0'; |
elsif (rising_edge(CLK)) then |
if ((UB_LD or LB_LD) = '1') then |
irLD <= '1'; |
elsif (rLD = '1') then |
irLD <= '0'; |
end if; |
end if; |
end process; |
|
C_LD <= '1' when (count = x"01") else |
'1' when (rLD = '1') else |
'0'; |
|
C_CE <= '1' when (rate > x"01") else |
'0'; |
|
U3 : gh_counter_down_ce_ld |
Generic Map (size => 16) |
PORT MAP ( |
clk => BR_clk, |
rst => rst, |
LOAD => C_LD, |
CE => C_CE, |
D => rate, |
Q => count); |
|
end a; |
|
/library/gh_shift_reg_se_sl.vhd
0,0 → 1,57
----------------------------------------------------------------------------- |
-- Filename: gh_shift_reg_se_sl.vhd |
-- |
-- Description: |
-- a shift register with async reset and count enable |
-- |
-- Copyright (c) 2006 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 02/11/06 G Huber Initial revision |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
|
ENTITY gh_shift_reg_se_sl IS |
GENERIC (size: INTEGER := 16); |
PORT( |
clk : IN STD_logic; |
rst : IN STD_logic; |
srst : IN STD_logic:='0'; |
SE : IN STD_logic; -- shift enable |
D : IN STD_LOGIC; |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END entity ; |
|
ARCHITECTURE a OF gh_shift_reg_se_sl IS |
|
signal iQ : STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
|
BEGIN |
|
Q <= iQ; |
|
process(clk,rst) |
begin |
if (rst = '1') then |
iQ <= (others => '0'); |
elsif (rising_edge(clk)) then |
if (srst = '1') then |
iQ <= (others => '0'); |
elsif (SE = '1') then |
iQ(size-1) <= D; |
iQ(size-2 downto 0) <= iQ(size-1 downto 1); |
end if; |
end if; |
end process; |
|
|
END a; |
|
/library/gh_DECODE_3to8.vhd
0,0 → 1,50
----------------------------------------------------------------------------- |
-- Filename: gh_DECODE_3to8.vhd |
-- |
-- Description: |
-- a 3 to 8 decoder |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 09/17/05 G Huber Initial revision |
-- 1.1 05/05/06 G Huber fix typo |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
ENTITY gh_decode_3to8 IS |
PORT( |
A : IN STD_LOGIC_VECTOR(2 DOWNTO 0); -- address |
G1 : IN STD_LOGIC; -- enable positive |
G2n : IN STD_LOGIC; -- enable negative |
G3n : IN STD_LOGIC; -- enable negative |
Y : out STD_LOGIC_VECTOR(7 downto 0) |
); |
END gh_decode_3to8 ; |
|
ARCHITECTURE a OF gh_decode_3to8 IS |
|
|
BEGIN |
|
Y <= x"00" when (G3n = '1') else |
x"00" when (G2n = '1') else |
x"00" when (G1 = '0') else |
x"80" when (A= o"7") else |
x"40" when (A= o"6") else |
x"20" when (A= o"5") else |
x"10" when (A= o"4") else |
x"08" when (A= o"3") else |
x"04" when (A= o"2") else |
x"02" when (A= o"1") else |
x"01";-- when (A= o"0") |
|
|
END a; |
|
/library/gh_edge_det.vhd
0,0 → 1,59
----------------------------------------------------------------------------- |
-- Filename: gh_edge_det.vhd |
-- |
-- Description: |
-- an edge detector - |
-- finds the rising edge and falling edge |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 09/10/05 G Huber Initial revision |
-- 2.0 09/17/05 h lefevre name change to avoid conflict |
-- with other libraries |
-- 2.1 05/21/06 S A Dodd fix typo's |
-- |
----------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
|
entity gh_edge_det is |
port( |
clk : in STD_LOGIC; |
rst : in STD_LOGIC; |
D : in STD_LOGIC; |
re : out STD_LOGIC; -- rising edge (need sync source at D) |
fe : out STD_LOGIC; -- falling edge (need sync source at D) |
sre : out STD_LOGIC; -- sync'd rising edge |
sfe : out STD_LOGIC -- sync'd falling edge |
); |
end gh_edge_det; |
|
|
architecture a of gh_edge_det is |
|
signal Q0, Q1 : std_logic; |
|
begin |
|
re <= D and (not Q0); |
fe <= (not D) and Q0; |
sre <= Q0 and (not Q1); |
sfe <= (not Q0) and Q1; |
|
process(clk,rst) |
begin |
if (rst = '1') then |
Q0 <= '0'; |
Q1 <= '0'; |
elsif (rising_edge(clk)) then |
Q0 <= D; |
Q1 <= Q0; |
end if; |
end process; |
|
end a; |
/library/gh_jkff.vhd
0,0 → 1,58
----------------------------------------------------------------------------- |
-- Filename: gh_jkff.vhd |
-- |
-- Description: |
-- a JK Flip-Flop |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 09/03/05 G Huber Initial revision |
-- 2.0 10/06/05 G Huber name change to avoid conflict |
-- with other libraries |
-- 2.1 05/21/06 S A Dodd fix typo's |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
|
ENTITY gh_jkff IS |
PORT( |
clk : IN STD_logic; |
rst : IN STD_logic; |
J,K : IN STD_logic; |
Q : OUT STD_LOGIC |
); |
END gh_jkff; |
|
ARCHITECTURE a OF gh_jkff IS |
|
signal iQ : STD_LOGIC; |
|
BEGIN |
|
Q <= iQ; |
|
process(clk,rst) |
begin |
if (rst = '1') then |
iQ <= '0'; |
elsif (rising_edge(clk)) then |
if ((J = '1') and (K = '1')) then |
iQ <= not iQ; |
elsif (J = '1') then |
iQ <= '1'; |
elsif (K = '1') then |
iQ <= '0'; |
end if; |
end if; |
end process; |
|
|
END a; |
|
/library/gh_parity_gen_Serial.vhd
0,0 → 1,53
----------------------------------------------------------------------------- |
-- Filename: gh_parity_gen_Serial.vhd |
-- |
-- Description: |
-- a Serial parity bit generator |
-- |
-- Copyright (c) 2005 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- -------- ----------- |
-- 1.0 10/15/05 S A Dodd Initial revision |
-- |
----------------------------------------------------------------------------- |
LIBRARY ieee; |
USE ieee.std_logic_1164.all; |
|
ENTITY gh_parity_gen_Serial IS |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
srst : in STD_LOGIC; |
SD : in STD_LOGIC; -- sample data pulse |
D : in STD_LOGIC; -- data |
Q : out STD_LOGIC -- parity |
); |
END gh_parity_gen_Serial; |
|
ARCHITECTURE a OF gh_parity_gen_Serial IS |
|
signal parity : std_logic; |
|
BEGIN |
|
Q <= parity; |
|
process (clk,rst) |
begin |
if (rst = '1') then |
parity <= '0'; |
elsif (rising_edge(clk)) then |
if (srst = '1') then -- need to clear before start of data word |
parity <= '0'; |
elsif (SD = '1') then -- sample data bit for parity generation |
parity <= (parity xor D); |
end if; |
end if; |
end process; |
|
END a; |
|
/gh_uart_Rx_8bit.vhd
0,0 → 1,352
----------------------------------------------------------------------------- |
-- Filename: gh_uart_Rx_8bit.vhd |
-- |
-- Description: |
-- an 8 bit UART Rx Module |
-- |
-- Copyright (c) 2006 by H LeFevre |
-- A VHDL 16550 UART core |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 02/18/06 H LeFevre Initial revision |
-- 1.1 02/25/06 H LeFevre mod to SM, goes to idle faster |
-- if no break error |
-- 2.0 06/18/07 P.Azkarate Define "range" in R_WCOUNT and R_brdCOUNT signals |
----------------------------------------------------------------------------- |
library ieee ; |
use ieee.std_logic_1164.all ; |
|
entity gh_uart_Rx_8bit is |
port( |
clk : in std_logic; -- clock |
rst : in std_logic; |
BRCx16 : in std_logic; -- 16x clock enable |
sRX : in std_logic; |
num_bits : in integer; |
Parity_EN : in std_logic; |
Parity_EV : in std_logic; |
Parity_ER : out std_logic; |
Frame_ER : out std_logic; |
Break_ITR : out std_logic; |
D_RDY : out std_logic; |
D : out std_logic_vector(7 downto 0) |
); |
end entity; |
|
architecture a of gh_uart_Rx_8bit is |
|
COMPONENT gh_shift_reg_se_sl is |
GENERIC (size: INTEGER := 16); |
PORT( |
clk : IN STD_logic; |
rst : IN STD_logic; |
srst : IN STD_logic:='0'; |
SE : IN STD_logic; -- shift enable |
D : IN STD_LOGIC; |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END COMPONENT; |
|
COMPONENT gh_parity_gen_Serial is |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
srst : in STD_LOGIC; |
SD : in STD_LOGIC; -- sample data pulse |
D : in STD_LOGIC; -- data |
Q : out STD_LOGIC |
); |
END COMPONENT; |
|
COMPONENT gh_counter_integer_down IS |
generic(max_count : integer := 8); |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : in STD_LOGIC; -- load D |
CE : IN STD_LOGIC; -- count enable |
D : in integer RANGE 0 TO max_count; |
Q : out integer RANGE 0 TO max_count |
); |
END COMPONENT; |
|
COMPONENT gh_jkff is |
PORT( |
clk : IN STD_logic; |
rst : IN STD_logic; |
J,K : IN STD_logic; |
Q : OUT STD_LOGIC |
); |
END COMPONENT; |
|
type R_StateType is (idle,R_start_bit,shift_data,R_parity, |
R_stop_bit,break_err); |
signal R_state, R_nstate : R_StateType; |
|
signal parity : std_logic; |
signal parity_Grst : std_logic; |
signal RWC_LD : std_logic; |
signal R_WCOUNT : integer range 0 to 15; |
signal s_DATA_LD : std_logic; |
signal chk_par : std_logic; |
signal chk_frm : std_logic; |
signal clr_brk : std_logic; |
signal clr_D : std_logic; |
signal s_chk_par : std_logic; |
signal s_chk_frm : std_logic; |
signal R_shift_reg : std_logic_vector(7 downto 0); |
signal iRX : std_logic; |
signal BRC : std_logic; |
signal dCLK_LD : std_logic; |
signal R_brdCOUNT : integer range 0 to 15; |
signal iParity_ER : std_logic; |
signal iFrame_ER : std_logic; |
signal iBreak_ITR : std_logic; |
signal iD_RDY : std_logic; |
|
begin |
|
---------------------------------------------- |
---- outputs---------------------------------- |
---------------------------------------------- |
process(CLK,rst) |
begin |
if (rst = '1') then |
Parity_ER <= '0'; |
Frame_ER <= '0'; |
Break_ITR <= '0'; |
D_RDY <= '0'; |
elsif (rising_edge(CLK)) then |
if (BRCx16 = '1') then |
D_RDY <= iD_RDY; |
if (iD_RDY = '1') then |
Parity_ER <= iParity_ER; |
Frame_ER <= iFrame_ER; |
Break_ITR <= iBreak_ITR; |
end if; |
end if; |
end if; |
end process; |
|
D <= R_shift_reg when (num_bits = 8) else |
('0' & R_shift_reg(7 downto 1)) when (num_bits = 7) else |
("00" & R_shift_reg(7 downto 2)) when (num_bits = 6) else |
("000" & R_shift_reg(7 downto 3)); -- when (bits_word = 5) else |
|
|
---------------------------------------------- |
|
dCLK_LD <= '1' when (R_state = idle) else |
'0'; |
|
BRC <= '0' when (BRCx16 = '0') else |
'1' when (R_brdCOUNT = 0) else |
'0'; |
|
u1 : gh_counter_integer_down -- baud rate divider |
generic map (15) |
port map( |
clk => clk, |
rst => rst, |
LOAD => dCLK_LD, |
CE => BRCx16, |
D => 14, |
Q => R_brdCOUNT); |
|
---------------------------------------------------------- |
|
U2 : gh_shift_reg_se_sl |
Generic Map(8) |
PORT MAP ( |
clk => clk, |
rst => rst, |
srst => clr_D, |
SE => s_DATA_LD, |
D => sRX, |
Q => R_shift_reg); |
|
----------------------------------------------------------- |
|
chk_par <= s_chk_par and (((parity xor iRX) and Parity_EV) |
or (((not parity) xor iRX) and (not Parity_EV))); |
|
U2c : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => chk_par, |
k => dCLK_LD, |
Q => iParity_ER); |
|
chk_frm <= s_chk_frm and (not iRX); |
|
U2d : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => chk_frm, |
k => dCLK_LD, |
Q => iFrame_ER); |
|
U2e : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => clr_d, |
k => clr_brk, |
Q => iBreak_ITR); |
|
-------------------------------------------------------------- |
-------------------------------------------------------------- |
|
|
process(R_state,BRCx16,BRC,iRX,R_WCOUNT,Parity_EN,R_brdCOUNT,iBreak_ITR) |
begin |
case R_state is |
when idle => -- idle |
iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '1'; |
s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0'; |
clr_D <= '0'; |
if (iRX = '0') then |
R_nstate <= R_start_bit; |
else |
R_nstate <= idle; |
end if; |
when R_start_bit => -- |
iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '1'; |
s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0'; |
if (BRC = '1') then |
clr_D <= '1'; |
R_nstate <= shift_data; |
elsif ((R_brdCOUNT = 8) and (iRX = '1')) then -- false start bit detection |
clr_D <= '0'; |
R_nstate <= idle; |
else |
clr_D <= '0'; |
R_nstate <= R_start_bit; |
end if; |
when shift_data => -- send data bit |
iD_RDY <= '0'; RWC_LD <= '0'; |
s_chk_par <= '0'; s_chk_frm <= '0'; |
clr_D <= '0'; |
if (BRCx16 = '0') then |
s_DATA_LD <= '0'; clr_brk <= '0'; |
R_nstate <= shift_data; |
elsif (R_brdCOUNT = 8) then |
s_DATA_LD <= '1'; clr_brk <= iRX; |
R_nstate <= shift_data; |
elsif ((R_WCOUNT = 1) and (R_brdCOUNT = 0) and (Parity_EN = '1')) then |
s_DATA_LD <= '0'; clr_brk <= '0'; |
R_nstate <= R_parity; |
elsif ((R_WCOUNT = 1) and (R_brdCOUNT = 0)) then |
s_DATA_LD <= '0'; clr_brk <= '0'; |
R_nstate <= R_stop_bit; |
else |
s_DATA_LD <= '0'; clr_brk <= '0'; |
R_nstate <= shift_data; |
end if; |
when R_parity => -- check parity bit |
iD_RDY <= '0'; s_DATA_LD <= '0'; |
RWC_LD <= '0'; s_chk_frm <= '0'; |
clr_D <= '0'; |
if (BRCx16 = '0') then |
s_chk_par <= '0'; clr_brk <= '0'; |
R_nstate <= R_parity; |
elsif (R_brdCOUNT = 8) then |
s_chk_par <= '1'; clr_brk <= iRX; |
R_nstate <= R_parity; |
elsif (BRC = '1') then |
s_chk_par <= '0'; clr_brk <= '0'; |
R_nstate <= R_stop_bit; |
else |
s_chk_par <= '0'; clr_brk <= '0'; |
R_nstate <= R_parity; |
end if; |
when R_stop_bit => -- check stop bit |
s_DATA_LD <= '0'; RWC_LD <= '0'; |
s_chk_par <= '0'; clr_brk <= iRX; |
clr_D <= '0'; |
if ((BRC = '1') and (iBreak_ITR = '1')) then |
iD_RDY <= '1'; s_chk_frm <= '0'; |
R_nstate <= break_err; |
elsif (BRC = '1') then |
iD_RDY <= '1'; s_chk_frm <= '0'; |
R_nstate <= idle; |
elsif (R_brdCOUNT = 8) then |
iD_RDY <= '0'; s_chk_frm <= '1'; |
R_nstate <= R_stop_bit; |
elsif ((R_brdCOUNT = 7) and (iBreak_ITR = '0')) then -- added 02/20/06 |
iD_RDY <= '1'; s_chk_frm <= '0'; |
R_nstate <= idle; |
else |
iD_RDY <= '0'; s_chk_frm <= '0'; |
R_nstate <= R_stop_bit; |
end if; |
when break_err => |
iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '0'; |
s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0'; |
clr_D <= '0'; |
if (iRX = '1') then |
R_nstate <= idle; |
else |
R_nstate <= break_err; |
end if; |
when others => |
iD_RDY <= '0'; s_DATA_LD <= '0'; RWC_LD <= '0'; |
s_chk_par <= '0'; s_chk_frm <= '0'; clr_brk <= '0'; |
clr_D <= '0'; |
R_nstate <= idle; |
end case; |
end process; |
|
-- |
-- registers for SM |
process(CLK,rst) |
begin |
if (rst = '1') then |
iRX <= '1'; |
R_state <= idle; |
elsif (rising_edge(CLK)) then |
if (BRCx16 = '1') then |
iRX <= sRX; |
R_state <= R_nstate; |
else |
iRX <= iRX; |
R_state <= R_state; |
end if; |
end if; |
end process; |
|
u3 : gh_counter_integer_down -- word counter |
generic map (8) |
port map( |
clk => clk, |
rst => rst, |
LOAD => RWC_LD, |
CE => BRC, |
D => num_bits, |
Q => R_WCOUNT |
); |
|
-------------------------------------------------------- |
-------------------------------------------------------- |
|
parity_Grst <= '1' when (R_state = R_start_bit) else |
'0'; |
|
U4 : gh_parity_gen_Serial |
PORT MAP ( |
clk => clk, |
rst => rst, |
srst => parity_Grst, |
SD => BRC, |
D => R_shift_reg(7), |
Q => parity); |
|
|
end a; |
|
/gh_fifo_async16_sr.vhd
0,0 → 1,210
--------------------------------------------------------------------- |
-- Filename: gh_fifo_async_sr.vhd |
-- |
-- |
-- Description: |
-- an Asynchronous FIFO, |
-- using "Style #2" gray code address compare |
-- |
-- Copyright (c) 2006, 2008 by George Huber |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 12/23/06 h lefevre Initial revision |
-- 1.1 09/20/08 hlefevre add simulation init |
-- (to '0') to ram data |
-- |
-------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_unsigned.all; |
USE ieee.std_logic_arith.all; |
|
entity gh_fifo_async16_sr is |
GENERIC (add_width: INTEGER :=3; -- min value is 2 (4 memory locations) |
data_width: INTEGER :=8 ); -- size of data bus |
port ( |
clk_WR : in STD_LOGIC; -- write clock |
clk_RD : in STD_LOGIC; -- read clock |
rst : in STD_LOGIC; -- resets counters |
srst : in STD_LOGIC:='0'; -- resets counters (sync with clk_WR) |
WR : in STD_LOGIC; -- write control |
RD : in STD_LOGIC; -- read control |
D : in STD_LOGIC_VECTOR (data_width-1 downto 0); |
Q : out STD_LOGIC_VECTOR (data_width-1 downto 0); |
empty : out STD_LOGIC; |
full : out STD_LOGIC); |
end entity; |
|
architecture a of gh_fifo_async16_sr is |
|
type ram_mem_type is array (2**add_width-1 downto 0) |
of STD_LOGIC_VECTOR (data_width-1 downto 0); |
signal ram_mem : ram_mem_type := (others => (others => '0')); |
signal iempty : STD_LOGIC; |
signal ifull : STD_LOGIC; |
signal add_WR_CE : std_logic; |
signal add_WR : std_logic_vector(add_width downto 0); -- add_width -1 bits are used to address MEM |
signal add_WR_GC : std_logic_vector(add_width downto 0); -- add_width bits are used to compare |
signal n_add_WR : std_logic_vector(add_width downto 0); -- for empty, full flags |
signal add_WR_RS : std_logic_vector(add_width downto 0); -- synced to read clk |
signal add_RD_CE : std_logic; |
signal add_RD : std_logic_vector(add_width downto 0); |
signal add_RD_GC : std_logic_vector(add_width downto 0); |
signal add_RD_GCwc : std_logic_vector(add_width downto 0); |
signal n_add_RD : std_logic_vector(add_width downto 0); |
signal add_RD_WS : std_logic_vector(add_width downto 0); -- synced to write clk |
signal srst_w : STD_LOGIC; |
signal isrst_w : STD_LOGIC; |
signal srst_r : STD_LOGIC; |
signal isrst_r : STD_LOGIC; |
|
begin |
|
-------------------------------------------- |
------- memory ----------------------------- |
-------------------------------------------- |
|
process (clk_WR) |
begin |
if (rising_edge(clk_WR)) then |
if ((WR = '1') and (ifull = '0')) then |
ram_mem(CONV_INTEGER(add_WR(add_width-1 downto 0))) <= D; |
end if; |
end if; |
end process; |
|
Q <= ram_mem(CONV_INTEGER(add_RD(add_width-1 downto 0))); |
|
----------------------------------------- |
----- Write address counter ------------- |
----------------------------------------- |
|
add_WR_CE <= '0' when (ifull = '1') else |
'0' when (WR = '0') else |
'1'; |
|
n_add_WR <= add_WR + "01"; |
|
process (clk_WR,rst) |
begin |
if (rst = '1') then |
add_WR <= (others => '0'); |
add_RD_WS(add_width downto add_width-1) <= "11"; |
add_RD_WS(add_width-2 downto 0) <= (others => '0'); |
add_WR_GC <= (others => '0'); |
elsif (rising_edge(clk_WR)) then |
add_RD_WS <= add_RD_GCwc; |
if (srst_w = '1') then |
add_WR <= (others => '0'); |
add_WR_GC <= (others => '0'); |
elsif (add_WR_CE = '1') then |
add_WR <= n_add_WR; |
for i in 0 to add_width-1 loop |
add_WR_GC(i) <= n_add_WR(i) xor n_add_WR(i+1); |
end loop; |
add_WR_GC(add_width) <= n_add_WR(add_width); |
else |
add_WR <= add_WR; |
add_WR_GC <= add_WR_GC; |
end if; |
end if; |
end process; |
|
full <= ifull; |
|
ifull <= '0' when (iempty = '1') else -- just in case add_RD_WS is reset to all zero's |
'0' when (add_RD_WS /= add_WR_GC) else ---- instend of "11 zero's" |
'1'; |
|
----------------------------------------- |
----- Read address counter -------------- |
----------------------------------------- |
|
|
add_RD_CE <= '0' when (iempty = '1') else |
'0' when (RD = '0') else |
'1'; |
|
n_add_RD <= add_RD + "01"; |
|
process (clk_RD,rst) |
begin |
if (rst = '1') then |
add_RD <= (others => '0'); |
add_WR_RS <= (others => '0'); |
add_RD_GC <= (others => '0'); |
add_RD_GCwc(add_width downto add_width-1) <= "11"; |
add_RD_GCwc(add_width-2 downto 0) <= (others => '0'); |
elsif (rising_edge(clk_RD)) then |
add_WR_RS <= add_WR_GC; |
if (srst_r = '1') then |
add_RD <= (others => '0'); |
add_RD_GC <= (others => '0'); |
add_RD_GCwc(add_width downto add_width-1) <= "11"; |
add_RD_GCwc(add_width-2 downto 0) <= (others => '0'); |
elsif (add_RD_CE = '1') then |
add_RD <= n_add_RD; |
for j in 0 to add_width-1 loop |
add_RD_GC(j) <= n_add_RD(j) xor n_add_RD(j+1); |
end loop; |
add_RD_GC(add_width) <= n_add_RD(add_width); |
for k in 0 to add_width-2 loop |
add_RD_GCwc(k) <= n_add_RD(k) xor n_add_RD(k+1); |
end loop; |
add_RD_GCwc(add_width-1) <= n_add_RD(add_width-1) xor (not n_add_RD(add_width)); |
add_RD_GCwc(add_width) <= (not n_add_RD(add_width)); |
else |
add_RD <= add_RD; |
add_RD_GC <= add_RD_GC; |
add_RD_GCwc <= add_RD_GCwc; |
end if; |
end if; |
end process; |
|
empty <= iempty; |
|
iempty <= '1' when (add_WR_RS = add_RD_GC) else |
'0'; |
|
---------------------------------- |
--- sync rest stuff -------------- |
--- srst is sync with clk_WR ----- |
--- srst_r is sync with clk_RD --- |
---------------------------------- |
|
process (clk_WR,rst) |
begin |
if (rst = '1') then |
srst_w <= '0'; |
isrst_r <= '0'; |
elsif (rising_edge(clk_WR)) then |
isrst_r <= srst_r; |
if (srst = '1') then |
srst_w <= '1'; |
elsif (isrst_r = '1') then |
srst_w <= '0'; |
end if; |
end if; |
end process; |
|
process (clk_RD,rst) |
begin |
if (rst = '1') then |
srst_r <= '0'; |
isrst_w <= '0'; |
elsif (rising_edge(clk_RD)) then |
isrst_w <= srst_w; |
if (isrst_w = '1') then |
srst_r <= '1'; |
else |
srst_r <= '0'; |
end if; |
end if; |
end process; |
|
end architecture; |
/gh_uart_16550.vhd
0,0 → 1,994
----------------------------------------------------------------------------- |
-- Filename: gh_uart_16550.vhd |
-- |
-- Description: |
-- designed to be a 16550 compatible UART |
-- |
-- Copyright (c) 2006, 2007, 2008 by H LeFevre |
-- A VHDL 16550 UART core |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 02/25/06 H LeFevre Initial revision |
-- 1.1 03/18/06 H LeFevre mod to clear THREmpty interrupt |
-- with IIR read |
-- 1.2 04/08/06 H LeFevre add time out interrupt |
-- 1.3 04/19/06 H LeFevre fix read fifo signal, so fifo |
-- will not lose data when baud rate |
-- generator is read |
-- 2.0 12/13/06 H LeFevre Fixed THRE interrupt, as recommended |
-- by Walter Hogan 12/12/06 |
-- 2.1 12/23/06 H LeFevre replace fifo's |
-- 2.2 01/20/07 H LeFevre replace read fifo |
-- 2.3 02/22/07 B Chini Modified TOI Function To Work as Specified in 16550D manual |
-- 2.4 07/12/07 H LeFevre fix 6, 7 bits transfers (LCR bits 1,0 were swapped |
-- as pointed out by Matthias Klemm |
-- 2.5 08/03/07 H LeFevre Mod TOI to fix issues missed in 2.3 (enabled with receiveIRQ, |
-- time reset with receive word- as Specified in 16550D manual) |
-- 2.6 08/04/07 H LeFevre load TOI when receive IRQ disabled |
-- 2.7 10/12/07 H LeFevre fix LSR Interrupt, as suggested by Matthias Klemm |
-- + mod to THRE Interrupt now, will be generated |
-- when enabled while trans FIFO is empty |
-- (opencore bug report) |
-- 2.7 10/13/07 H LeFevre mod LSR Interrupt so that it will retrigger with |
-- back to back errors |
-- 2.8 07/21/08 H LeFevre mod equ for iBreak_ITR [add (and (not RF_EMPTY))] |
-- as suggested by Nathan Z. |
-- 2.9 08/18/11 A Borga updated gh_fifo_async16_sr: fixed bug with pointers init |
-- |
-- |
----------------------------------------------------------------------------- |
library ieee ; |
use ieee.std_logic_1164.all ; |
|
entity gh_uart_16550 is |
port( |
clk : in std_logic; -- Main clock |
BR_clk : in std_logic; -- Baudrate generator clock TX and RX |
rst : in std_logic; -- Reset |
rst_buffer : in std_logic; -- Reset for FIFO and TX and RX |
CS : in std_logic; -- Chip select -> 1 Cycle long CS strobe = 1 data send |
WR : in std_logic; -- WRITE when HIGH with CS high | READ when LOW with CS high |
ADD : in std_logic_vector(2 downto 0); -- Address bus |
D : in std_logic_vector(7 downto 0); -- Input DATA BUS |
|
sRX : in std_logic; -- Lantronix's OUTPUT |
CTSn : in std_logic := '1'; |
DSRn : in std_logic := '1'; |
RIn : in std_logic := '1'; |
DCDn : in std_logic := '1'; |
|
sTX : out std_logic; -- Lantronix's INPUT |
DTRn : out std_logic; -- not used |
RTSn : out std_logic; -- not used |
OUT1n : out std_logic; -- not used |
OUT2n : out std_logic; -- not used |
TXRDYn : out std_logic; -- Tx FIFO Data Ready |
RXRDYn : out std_logic; -- Rx FIFO Data Ready |
|
IRQ : out std_logic; -- not used |
B_CLK : out std_logic; -- 16x Baudrate clock output |
RD : out std_logic_vector(7 downto 0) -- Output DATA BUS |
); |
end entity; |
|
architecture a of gh_uart_16550 is |
|
COMPONENT gh_edge_det is |
PORT( |
clk : in STD_LOGIC; |
rst : in STD_LOGIC; |
D : in STD_LOGIC; |
re : out STD_LOGIC; -- rising edge (need sync source at D) |
fe : out STD_LOGIC; -- falling edge (need sync source at D) |
sre : out STD_LOGIC; -- sync'd rising edge |
sfe : out STD_LOGIC -- sync'd falling edge |
); |
END COMPONENT; |
|
COMPONENT gh_register_ce is |
GENERIC (size: INTEGER := 8); |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
CE : IN STD_LOGIC; -- clock enable |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END COMPONENT; |
|
COMPONENT gh_DECODE_3to8 is |
port( |
A : IN STD_LOGIC_VECTOR(2 DOWNTO 0); -- address |
G1 : IN STD_LOGIC; -- enable positive |
G2n : IN STD_LOGIC; -- enable negitive |
G3n : IN STD_LOGIC; -- enable negitive |
Y : out STD_LOGIC_VECTOR(7 downto 0) |
); |
END COMPONENT; |
|
COMPONENT gh_jkff is |
PORT( |
clk : IN STD_logic; |
rst : IN STD_logic; |
J,K : IN STD_logic; |
Q : OUT STD_LOGIC |
); |
END COMPONENT; |
|
COMPONENT gh_uart_Tx_8bit is |
port( |
clk : in std_logic; -- clock |
rst : in std_logic; |
xBRC : in std_logic; -- x clock enable |
D_RYn : in std_logic; -- data ready |
D : in std_logic_vector(7 downto 0); |
num_bits : in integer:= 8; -- number of bits in transfer |
Break_CB : in std_logic; |
stopB : in std_logic; |
Parity_EN : in std_logic; |
Parity_EV : in std_logic; |
sTX : out std_logic; |
BUSYn : out std_logic; |
read : out std_logic -- data read |
); |
END COMPONENT; |
|
COMPONENT gh_uart_Rx_8bit is |
port( |
clk : in std_logic; -- clock |
rst : in std_logic; |
BRCx16 : in std_logic; -- 16x clock enable |
sRX : in std_logic; |
num_bits : in integer; |
Parity_EN : in std_logic; |
Parity_EV : in std_logic; |
Parity_ER : out std_logic; |
Frame_ER : out std_logic; |
Break_ITR : out std_logic; |
D_RDY : out std_logic; |
D : out std_logic_vector(7 downto 0) |
); |
END COMPONENT; |
|
COMPONENT gh_fifo_async16_sr is |
GENERIC (data_width: INTEGER :=8 ); -- size of data bus |
port ( |
clk_WR : in STD_LOGIC; -- write clock |
clk_RD : in STD_LOGIC; -- read clock |
rst : in STD_LOGIC; -- resets counters |
srst : in STD_LOGIC; -- resets counters |
WR : in STD_LOGIC; -- write control |
RD : in STD_LOGIC; -- read control |
D : in STD_LOGIC_VECTOR (data_width-1 downto 0); |
Q : out STD_LOGIC_VECTOR (data_width-1 downto 0); |
empty : out STD_LOGIC; |
full : out STD_LOGIC); |
END COMPONENT; |
|
COMPONENT gh_baud_rate_gen is |
port( |
clk : in std_logic; |
rst : in std_logic; |
BR_clk : in std_logic; |
WR : in std_logic; |
BE : in std_logic_vector (1 downto 0); -- byte enable |
D : in std_logic_vector (15 downto 0); |
RD : out std_logic_vector (15 downto 0); |
rCE : out std_logic; |
rCLK : out std_logic |
); |
END COMPONENT; |
|
COMPONENT gh_fifo_async16_rcsr_wf is |
GENERIC (data_width: INTEGER :=8 ); -- size of data bus |
port ( |
clk_WR : in STD_LOGIC; -- write clock |
clk_RD : in STD_LOGIC; -- read clock |
rst : in STD_LOGIC; -- resets counters |
rc_srst : in STD_LOGIC:='0'; -- resets counters (sync with clk_RD!!!) |
WR : in STD_LOGIC; -- write control |
RD : in STD_LOGIC; -- read control |
D : in STD_LOGIC_VECTOR (data_width-1 downto 0); |
Q : out STD_LOGIC_VECTOR (data_width-1 downto 0); |
empty : out STD_LOGIC; -- sync with clk_RD!!! |
q_full : out STD_LOGIC; -- sync with clk_RD!!! |
h_full : out STD_LOGIC; -- sync with clk_RD!!! |
a_full : out STD_LOGIC; -- sync with clk_RD!!! |
full : out STD_LOGIC); |
END COMPONENT; |
|
COMPONENT gh_counter_down_ce_ld_tc IS |
GENERIC (size: INTEGER :=8); |
PORT( |
CLK : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : IN STD_LOGIC; |
CE : IN STD_LOGIC; |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
TC : OUT STD_LOGIC |
); |
END COMPONENT; |
|
COMPONENT gh_edge_det_XCD is -- added 2 aug 2007 |
port( |
iclk : in STD_LOGIC; -- clock for input data signal |
oclk : in STD_LOGIC; -- clock for output data pulse |
rst : in STD_LOGIC; |
D : in STD_LOGIC; |
re : out STD_LOGIC; -- rising edge |
fe : out STD_LOGIC -- falling edge |
); |
END COMPONENT; |
|
signal IER : std_logic_vector(3 downto 0); -- Interrupt Enable Register |
signal IIR : std_logic_vector(7 downto 0); -- Interrupt ID Register |
signal iIIR : std_logic_vector(3 downto 0); -- 12/23/06 |
signal FCR : std_logic_vector(7 downto 0); -- FIFO Control register |
signal LCR : std_logic_vector(7 downto 0); -- Line Control Register |
signal MCR : std_logic_vector(4 downto 0); -- Modem Control Register |
signal LSR : std_logic_vector(7 downto 0); -- Line Status Register |
signal MSR : std_logic_vector(7 downto 0); -- Modem Status Register |
signal SCR : std_logic_vector(7 downto 0); -- Line Control Register |
signal RDD : std_logic_vector(15 downto 0); -- Divisor Latch |
signal iMSR : std_logic_vector(7 downto 4); -- Modem Status Register |
signal RD_IIR : std_logic; |
|
signal iRD : std_logic_vector(7 downto 0); |
signal CSn : std_logic; |
signal WR_B : std_logic_vector(7 downto 0); |
signal WR_F : std_logic; |
signal WR_IER : std_logic; |
signal WR_D : std_logic; |
signal WR_DML : std_logic_vector(1 downto 0); |
signal D16 : std_logic_vector(15 downto 0); |
signal BRC16x : std_logic; -- baud rate clock |
|
signal ITR0 : std_logic; |
signal isITR1 : std_logic; |
signal sITR1 : std_logic; |
signal cITR1 : std_logic; |
signal cITR1a : std_logic; |
signal ITR1 : std_logic; |
signal ITR2 : std_logic; |
signal ITR3 : std_logic; |
|
signal DCTS : std_logic; |
signal CTSn_RE : std_logic; |
signal CTSn_FE : std_logic; |
signal iDCTS : std_logic; |
signal iLOOP : std_logic; |
|
signal DDSR : std_logic; |
signal DSRn_RE : std_logic; |
signal DSRn_FE : std_logic; |
signal iDDSR : std_logic; |
|
signal TERI : std_logic; |
signal RIn_RE : std_logic; |
|
signal DDCD : std_logic; |
signal DCDn_RE : std_logic; |
signal DCDn_FE : std_logic; |
signal iDDCD : std_logic; |
|
signal RD_MSR : std_logic; |
signal MSR_CLR : std_logic; |
|
signal RD_LSR : std_logic; |
signal LSR_CLR : std_logic; |
|
signal num_bits : integer:=0; |
signal stopB : std_logic; |
signal Parity_EN : std_logic; |
signal Parity_OD : std_logic; |
signal Parity_EV : std_logic; |
-- signal Parity_sticky : std_logic; |
signal Break_CB : std_logic; |
|
signal TF_RD : std_logic; |
signal TF_CLR : std_logic; |
signal TF_CLRS : std_logic; |
signal TF_DO : std_logic_vector(7 downto 0); |
signal TF_empty : std_logic; |
signal TF_full : std_logic; |
|
signal RF_WR : std_logic; |
signal RF_RD : std_logic; |
signal RF_RD_brs : std_logic; -- added 3 aug 2007 |
signal RF_CLR : std_logic; |
signal RF_CLRS : std_logic; |
signal RF_DI : std_logic_vector(10 downto 0); -- Read FIFO data input |
signal RF_DO : std_logic_vector(10 downto 0); -- Read FIFO data output |
signal RF_empty : std_logic; |
signal RF_full : std_logic; |
signal RD_RDY : std_logic; |
|
signal iParity_ER : std_logic; -- added 13 oct 2007 |
signal iFRAME_ER : std_logic; -- added 13 oct 2007 |
signal iBreak_ITR : std_logic; -- added 13 oct 2007 |
signal Parity_ER : std_logic; |
signal FRAME_ER : std_logic; |
signal Break_ITR : std_logic; |
signal TSR_EMPTY : std_logic; |
signal OVR_ER : std_logic; |
signal isTX : std_logic; |
signal isRX : std_logic; |
|
signal q_full : std_logic; |
signal h_full : std_logic; |
signal a_full : std_logic; |
|
signal RF_ER : std_logic; |
signal TX_RDY : std_logic; |
signal TX_RDYS : std_logic; |
signal TX_RDYC : std_logic; |
signal RX_RDY : std_logic; |
signal RX_RDYS : std_logic; |
signal RX_RDYC : std_logic; |
|
signal TOI : std_logic; -- time out interrupt |
signal TOI_enc : std_logic; -- time out interrupt counter inable |
signal iTOI_enc : std_logic; |
signal TOI_set : std_logic; |
signal iTOI_set : std_logic; -- added 3 aug 2007 |
signal TOI_clr : std_logic; |
signal TOI_c_ld : std_logic; |
signal TOI_c_d : std_logic_vector(11 downto 0); |
|
begin |
|
---------------------------------------------- |
---- resd ---------------------------------- |
---------------------------------------------- |
|
RD <= RF_DO(7 downto 0) when ((ADD = o"0") and (LCR(7) = '0')) else |
(x"0" & IER) when ((ADD = o"1") and (LCR(7) = '0')) else |
IIR when (ADD = o"2") else |
LCR when (ADD = o"3") else |
("000" & MCR) when (ADD = o"4") else |
LSR when (ADD = o"5") else |
MSR when (ADD = o"6") else |
SCR when (ADD = o"7") else |
RDD(7 downto 0) when (ADD = o"0") else |
RDD(15 downto 8); |
|
---------------------------------------------- |
|
U1 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => TX_RDYS, |
k => TX_RDYC, |
Q => TX_RDY); |
|
TXRDYn <= (not TX_RDY); |
|
TX_RDYS <= '1' when ((FCR(3) = '0') and (TF_empty = '1') and (TSR_EMPTY = '1')) else |
'1' when ((FCR(3) = '1') and (TF_empty = '1')) else |
'0'; |
|
TX_RDYC <= '1' when ((FCR(3) = '0') and (TF_empty = '0')) else |
'1' when ((FCR(3) = '1') and (TF_full = '1')) else |
'0'; |
|
U2 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => RX_RDYS, |
k => RX_RDYC, |
Q => RX_RDY); |
|
RXRDYn <= (not RX_RDY); |
|
RX_RDYS <= '1' when ((FCR(3) = '0') and (RF_empty = '0')) else -- mod 01/20/07 |
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "11") and (a_full = '1')) else |
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "10") and (h_full = '1')) else |
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "01") and (q_full = '1')) else |
'1' when ((FCR(3) = '1') and (FCR(7 downto 6) = "00") and (RF_empty = '0')) else |
'0'; |
|
|
RX_RDYC <= '1' when (RF_empty = '1') else |
'0'; |
|
|
---------------------------------------------- |
---- Modem Status Register Bits -------------- |
---------------------------------------------- |
|
U3 : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => CTSn, |
sre => CTSn_RE, |
sfe => CTSn_FE); |
|
iDCTS <= CTSn_RE or CTSn_FE; |
|
U4 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => iDCTS, |
k => MSR_CLR, |
Q => DCTS); |
|
MSR(0) <= DCTS; |
|
U5 : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => DSRn, |
sre => DSRn_RE, |
sfe => DSRn_FE); |
|
iDDSR <= DSRn_RE or DSRn_FE; |
|
U6 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => iDDSR, |
k => MSR_CLR, |
Q => DDSR); |
|
MSR(1) <= DDSR; |
|
U7 : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => RIn, |
sre => RIn_RE); |
|
U8 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => RIn_RE, |
k => MSR_CLR, |
Q => TERI); |
|
MSR(2) <= TERI; |
|
U9 : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => DCDn, |
sre => DCDn_RE, |
sfe => DCDn_FE); |
|
iDDCD <= DCDn_RE or DCDn_FE; |
|
U10 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => iDDCD, |
k => MSR_CLR, |
Q => DDCD); |
|
MSR(3) <= DDCD; |
|
iMSR(4) <= (not CTSn) when (iLOOP = '0') else |
MCR(1); |
|
iMSR(5) <= (not DSRn) when (iLOOP = '0') else |
MCR(0); |
|
iMSR(6) <= (not RIn) when (iLOOP = '0') else |
MCR(2); |
|
iMSR(7) <= (not DCDn) when (iLOOP = '0') else |
MCR(3); |
|
RD_MSR <= '0' when ((CS = '0') or (WR = '1')) else |
'0' when (ADD /= o"6") else |
'1'; |
|
|
ITR0 <= '0' when (IER(3) = '0') else |
'1' when (MSR(3 downto 0) > x"0") else |
'0'; |
|
U11 : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => RD_MSR, |
sfe => MSR_CLR); |
|
u12 : gh_register_ce |
generic map (4) |
port map( |
clk => clk, |
rst => rst, |
ce => '1', |
D => iMSR, |
Q => MSR(7 downto 4) |
); |
|
--------------------------------------------------- |
-------- LSR -------------------------------------- |
--------------------------------------------------- |
|
LSR(0) <= (not RF_empty); |
|
U13 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => OVR_ER, |
k => LSR_CLR, |
Q => LSR(1)); |
|
OVR_ER <= '1' when ((RF_full = '1') and (RF_WR = '1')) else |
'0'; |
|
U14 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => PARITY_ER, |
k => LSR_CLR, |
Q => LSR(2)); |
|
U15 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => FRAME_ER, |
k => LSR_CLR, |
Q => LSR(3)); |
|
U16 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => Break_ITR, |
k => LSR_CLR, |
Q => LSR(4)); |
|
LSR(5) <= TF_EMPTY; |
LSR(6) <= TF_EMPTY and TSR_EMPTY; |
|
U17 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => RF_ER, |
k => LSR_CLR, |
Q => LSR(7)); |
|
RF_ER <= '1' when (RF_DI(10 downto 8) > "000") else |
'0'; |
|
RD_LSR <= '0' when ((CS = '0') or (WR = '1')) else |
'0' when (ADD /= o"5") else |
'1'; |
|
U18 : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => RD_LSR, |
sfe => LSR_CLR); |
|
---------------------------------------------- |
------ registers ------- |
---------------------------------------------- |
|
CSn <= (not CS); |
|
|
u19 : gh_DECODE_3to8 |
port map( |
A => ADD, |
G1 => WR, |
G2n => CSn, |
G3n => '0', |
Y => WR_B |
); |
|
WR_F <= WR_B(0) and (not LCR(7)); |
WR_IER <= WR_B(1) and (not LCR(7)); |
WR_D <= LCR(7) and (WR_B(0) or WR_B(1)); |
WR_DML <= (WR_B(1) and LCR(7)) & (WR_B(0) and LCR(7)); |
|
u20 : gh_register_ce |
generic map (4) |
port map( |
clk => clk, |
rst => rst, |
ce => WR_IER, |
D => D(3 downto 0), |
Q => IER |
); |
|
u21 : gh_register_ce |
generic map (8) |
port map( |
clk => clk, |
rst => rst, |
ce => WR_B(2), |
D => D, |
Q => FCR |
); |
|
U22 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => RF_CLRS, |
k => RF_EMPTY, |
Q => RF_CLR); |
|
RF_CLRS <= D(1) AND WR_B(2); |
|
U23 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => TF_CLRS, |
k => TF_EMPTY, |
Q => TF_CLR); |
|
TF_CLRS <= D(2) AND WR_B(2); |
|
u24 : gh_register_ce |
generic map (8) |
port map( |
clk => clk, |
rst => rst, |
ce => WR_B(3), |
D => D, |
Q => LCR |
); |
|
num_bits <= 5 when ((LCR(0) = '0') and (LCR(1) = '0')) else |
6 when ((LCR(0) = '1') and (LCR(1) = '0')) else -- 07/12/07 |
7 when ((LCR(0) = '0') and (LCR(1) = '1')) else -- 07/12/07 |
8; |
|
stopB <= LCR(2); |
|
Parity_EN <= LCR(3); |
Parity_OD <= LCR(3) and (not LCR(4)) and (not LCR(5)); |
Parity_EV <= LCR(3) and LCR(4) and (not LCR(5)); |
-- Parity_sticky <= LCR(3) and LCR(5); |
Break_CB <= LCR(6); |
|
u25 : gh_register_ce |
generic map (5) |
port map( |
clk => clk, |
rst => rst, |
ce => WR_B(4), |
D => D(4 downto 0), |
Q => MCR |
); |
|
DTRn <= (not MCR(0)) or iLOOP; |
RTSn <= (not MCR(1)) or iLOOP; |
OUT1n <= (not MCR(2)) or iLOOP; |
OUT2n <= (not MCR(3)) or iLOOP; |
iLOOP <= MCR(4); |
|
u26 : gh_register_ce |
generic map (8) |
port map( |
clk => clk, |
rst => rst, |
ce => WR_B(7), |
D => D, |
Q => SCR |
); |
|
---------------------------------------------------------- |
|
D16 <= D & D; |
|
u27 : gh_baud_rate_gen |
port map( |
clk => clk, |
BR_clk => BR_clk, |
rst => rst, |
WR => WR_D, |
BE => WR_DML, |
D => D16, |
RD => RDD, |
rCE => BRC16x, |
rCLK => B_clk |
); |
|
-------------------------------------------------- |
---- trans FIFO 12/23/06 ----------------------- |
-------------------------------------------------- |
|
U28 : gh_fifo_async16_sr |
Generic Map(data_width => 8) |
PORT MAP ( |
clk_WR => clk, |
clk_RD => BR_clk, |
rst => rst_buffer, |
srst => TF_CLR, |
WR => WR_F, |
RD => TF_RD, |
D => D, |
Q => TF_DO, |
empty => TF_empty, |
full => TF_full); |
|
---------------------------------------------------------------- |
----------- added 03/18/06 ------------------------------------- |
----------- mod 10/12/07 -------------------------------------- |
|
U28a : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => isITR1, |
sre => sITR1); |
|
isITR1 <= TF_empty and IER(1); |
|
---------- end mod 10/12/07 ----------------- |
|
RD_IIR <= '0' when (ADD /= o"2") else |
'0' when (WR = '1') else |
'0' when (CS = '0') else |
'0' when (IIR(3 downto 1) /= "001") else -- walter hogan 12/12/2006 |
'1'; |
|
U28b : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => RD_IIR, |
sfe => cITR1a); |
|
cITR1 <= cITR1a or (not TF_empty); |
|
U28c : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => sITR1, |
k => cITR1, |
Q => ITR1); |
|
----------- added 03/18/06 ------------------------------------------ |
--------------------------------------------------------------------- |
|
U29 : gh_UART_Tx_8bit |
PORT MAP ( |
clk => BR_clk, |
rst => rst_buffer, |
xBRC => BRC16x, |
D_RYn => TF_empty, |
D => TF_DO, |
num_bits => num_bits, |
Break_CB => Break_CB, |
StopB => stopB, |
Parity_EN => Parity_EN, |
Parity_EV => Parity_EV, |
sTX => isTX, |
BUSYn => TSR_EMPTY, |
read => TF_RD); |
|
sTX <= isTX; |
|
-------------------------------------------------- |
---- Receive FIFO ---------------------------------- |
-------------------------------------------------- |
|
U30 : gh_edge_det |
PORT MAP ( |
clk => BR_clk, |
rst => rst, |
d => RD_RDY, |
re => RF_WR); |
|
RF_RD <= '0' when (LCR(7) = '1') else -- added 04/19/06 |
'1' when ((ADD = "000") and (CS = '1') and (WR = '0')) else |
'0'; |
|
U31 : gh_fifo_async16_rcsr_wf -- 01/20/07 |
Generic Map(data_width => 11) |
PORT MAP ( |
clk_WR => BR_clk, |
clk_RD => clk, |
rst => rst_buffer, |
rc_srst => RF_CLR, |
WR => RF_WR, |
RD => RF_RD, |
D => RF_DI, |
Q => RF_DO, |
empty => RF_empty, |
q_full => q_full, |
h_full => h_full, |
a_full => a_full, |
full => RF_full); |
|
------------ 10/12/07 -------------------------------------- |
----- as suggested Matthias Klemm ------------------------- |
----- mod 10/13/07 ----------------------------------------- |
|
iParity_ER <= RF_DO(8) and (not RF_RD); |
|
U32a : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => iParity_ER, |
sre => Parity_ER); |
|
iFRAME_ER <= RF_DO(9) and (not RF_RD); |
|
U32b : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => iFRAME_ER, |
sre => FRAME_ER); |
|
iBreak_ITR <= RF_DO(10) and (not RF_RD) and (not RF_EMPTY); -- 07/21/08 |
|
U32c : gh_edge_det |
PORT MAP ( |
clk => clk, |
rst => rst, |
d => iBreak_ITR, |
sre => Break_ITR); |
|
ITR3 <= '0' when (IER(2) = '0') else |
'1' when (LSR(1) = '1') else |
'1' when (LSR(4 downto 2) > "000") else |
'0'; |
|
----------------------------------------------------------------------- |
|
|
isRX <= sRX when (iLOOP = '0') else |
isTX; |
|
|
ITR2 <= '0' when (IER(0) = '0') else -- mod 01/20/07 |
'1' when ((FCR(7 downto 6) = "11") and (a_full = '1')) else |
'1' when ((FCR(7 downto 6) = "10") and (h_full = '1')) else |
'1' when ((FCR(7 downto 6) = "01") and (q_full = '1')) else |
'1' when ((FCR(7 downto 6) = "00") and(RF_empty = '0')) else |
'0'; |
|
U33 : gh_UART_Rx_8bit |
PORT MAP ( |
clk => BR_clk, |
rst => rst_buffer, |
BRCx16 => BRC16x, |
sRX => isRX, |
num_bits => num_bits, |
Parity_EN => Parity_EN, |
Parity_EV => Parity_EV, |
Parity_ER => RF_DI(8), |
FRAME_ER => RF_DI(9), |
Break_ITR => RF_DI(10), |
D_RDY => RD_RDY, |
D => RF_DI(7 downto 0) |
); |
|
---------------------------------------------------------------- |
---------- added 04/08/06 time out interrupt ------------------- |
---------- once there a received data word is recieved, -------- |
---------- the counter will be running until ------------------- |
---------- FIFO is empty, counter reset on FIFO read or write -- |
------- mod 3 aug 2007 |
|
TOI_clr <= RF_empty or RF_RD or (not IER(0)); |
|
U34 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => TOI_set, |
k => TOI_clr, |
Q => TOI); |
|
U35 : gh_jkff |
PORT MAP ( |
clk => clk, |
rst => rst, |
j => LSR(0), -- enable time out counter with received data |
k => RF_empty, -- once FIFO is empty, stop counter |
Q => iTOI_enc); |
|
U35a : gh_edge_det_XCD |
PORT MAP ( |
iclk => clk, |
oclk => BR_clk, |
rst => rst, |
d => RF_RD, |
re => RF_RD_brs, |
fe => open); |
|
process(BR_clk,rst) |
begin |
if (rst = '1') then |
TOI_enc <= '0'; |
elsif (rising_edge(BR_clk)) then |
TOI_enc <= iTOI_enc; |
end if; |
end process; |
|
TOI_c_ld <= '1' when (IER(0) = '0') else -- added 4 aug 2007 |
'1' when (TOI_enc = '0') else |
'1' when (RF_RD_brs = '1') else |
'1' when (RF_WR = '1') else |
'0'; |
|
U36 : gh_counter_down_ce_ld_tc |
generic map(10) |
port map( |
clk => BR_clk, |
rst => rst, |
LOAD => TOI_c_ld, |
CE => BRC16x, |
D => TOI_c_d(9 downto 0), |
-- Q => , |
TC => iTOI_set |
); |
|
U36a : gh_edge_det_XCD |
PORT MAP ( |
iclk => BR_clk, |
oclk => clk, |
rst => rst, |
d => iTOI_set, |
re => TOI_set, |
fe => open); |
|
|
TOI_c_d <= x"1C0" when (num_bits = 5) else |
x"200" when (num_bits = 6) else |
x"240" when (num_bits = 7) else |
x"280";-- when (num_bits = 8) |
|
-------------------------------------------------------------- |
-------------------------------------------------------------- |
|
IRQ <= '1' when ((ITR3 or ITR2 or TOI or ITR1 or ITR0) = '1') else |
'0'; |
|
iIIR(0) <= '0' when ((ITR3 or ITR2 or TOI or ITR1 or ITR0) = '1') else |
'1'; |
|
iIIR(3 downto 1) <= "011" when (ITR3 = '1') else |
"010" when (ITR2 = '1') else |
"110" when (TOI = '1') else -- added 04/08/06 |
"001" when (ITR1 = '1') else |
"000"; |
|
IIR(7 downto 4) <= x"C"; -- FIFO's always enabled |
|
u37 : gh_register_ce -- 12/23/06 |
generic map (4) |
port map( |
clk => clk, |
rst => rst, |
ce => CSn, |
D => iIIR, |
Q => IIR(3 downto 0) |
); |
|
-------------------------------------------------------------- |
|
end a; |
/gh_fifo_async16_rcsr_wf.vhd
0,0 → 1,280
--------------------------------------------------------------------- |
-- Filename: gh_fifo_async16_rcsr_wf.vhd |
-- |
-- |
-- Description: |
-- a simple Asynchronous FIFO - uses FASM style Memory |
-- 16 word depth with UART level read flags |
-- has "Style #2" gray code address compare |
-- |
-- Copyright (c) 2007 by Howard LeFevre |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 01/20/07 h lefevre Initial revision |
-- |
-------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_unsigned.all; |
USE ieee.std_logic_arith.all; |
|
entity gh_fifo_async16_rcsr_wf is |
GENERIC (data_width: INTEGER :=8 ); -- size of data bus |
port ( |
clk_WR : in STD_LOGIC; -- write clock |
clk_RD : in STD_LOGIC; -- read clock |
rst : in STD_LOGIC; -- resets counters |
rc_srst : in STD_LOGIC:='0'; -- resets counters (sync with clk_RD!!!) |
WR : in STD_LOGIC; -- write control |
RD : in STD_LOGIC; -- read control |
D : in STD_LOGIC_VECTOR (data_width-1 downto 0); |
Q : out STD_LOGIC_VECTOR (data_width-1 downto 0); |
empty : out STD_LOGIC; -- sync with clk_RD!!! |
q_full : out STD_LOGIC; -- sync with clk_RD!!! |
h_full : out STD_LOGIC; -- sync with clk_RD!!! |
a_full : out STD_LOGIC; -- sync with clk_RD!!! |
full : out STD_LOGIC); |
end entity; |
|
architecture a of gh_fifo_async16_rcsr_wf is |
|
component gh_binary2gray IS |
GENERIC (size: INTEGER := 8); |
PORT( |
B : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
G : out STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
end component; |
|
component gh_gray2binary IS |
GENERIC (size: INTEGER := 8); |
PORT( |
G : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); -- gray code in |
B : out STD_LOGIC_VECTOR(size-1 DOWNTO 0) -- binary value out |
); |
end component; |
|
type ram_mem_type is array (15 downto 0) |
of STD_LOGIC_VECTOR (data_width-1 downto 0); |
signal ram_mem : ram_mem_type; |
signal iempty : STD_LOGIC; |
signal diempty : STD_LOGIC; |
signal ifull : STD_LOGIC; |
signal add_WR_CE : std_logic; |
signal add_WR : std_logic_vector(4 downto 0); -- add_width -1 bits are used to address MEM |
signal add_WR_GC : std_logic_vector(4 downto 0); -- add_width bits are used to compare |
signal iadd_WR_GC : std_logic_vector(4 downto 0); |
signal n_add_WR : std_logic_vector(4 downto 0); -- for empty, full flags |
signal add_WR_RS : std_logic_vector(4 downto 0); -- synced to read clk |
signal add_RD_CE : std_logic; |
signal add_RD : std_logic_vector(4 downto 0); |
signal add_RD_GC : std_logic_vector(4 downto 0); |
signal iadd_RD_GC : std_logic_vector(4 downto 0); |
signal add_RD_GCwc : std_logic_vector(4 downto 0); |
signal iadd_RD_GCwc : std_logic_vector(4 downto 0); |
signal iiadd_RD_GCwc : std_logic_vector(4 downto 0); |
signal n_add_RD : std_logic_vector(4 downto 0); |
signal add_RD_WS : std_logic_vector(4 downto 0); -- synced to write clk |
signal srst_w : STD_LOGIC; |
signal isrst_w : STD_LOGIC; |
signal srst_r : STD_LOGIC; |
signal isrst_r : STD_LOGIC; |
signal c_add_RD : std_logic_vector(4 downto 0); |
signal c_add_WR : std_logic_vector(4 downto 0); |
signal c_add : std_logic_vector(4 downto 0); |
|
begin |
|
-------------------------------------------- |
------- memory ----------------------------- |
-------------------------------------------- |
|
|
process (clk_WR) |
begin |
if (rising_edge(clk_WR)) then |
if ((WR = '1') and (ifull = '0')) then |
ram_mem(CONV_INTEGER(add_WR(3 downto 0))) <= D; |
end if; |
end if; |
end process; |
|
Q <= ram_mem(CONV_INTEGER(add_RD(3 downto 0))); |
|
----------------------------------------- |
----- Write address counter ------------- |
----------------------------------------- |
|
add_WR_CE <= '0' when (ifull = '1') else |
'0' when (WR = '0') else |
'1'; |
|
n_add_WR <= add_WR + "01"; |
|
U1 : gh_binary2gray |
generic map (size => 5) |
port map( |
B => n_add_WR, |
G => iadd_WR_GC |
); |
|
process (clk_WR,rst) |
begin |
if (rst = '1') then |
add_WR <= (others => '0'); |
add_RD_WS(4 downto 3) <= "11"; |
add_RD_WS(2 downto 0) <= (others => '0'); |
add_WR_GC <= (others => '0'); |
elsif (rising_edge(clk_WR)) then |
add_RD_WS <= add_RD_GCwc; |
if (srst_w = '1') then |
add_WR <= (others => '0'); |
add_WR_GC <= (others => '0'); |
elsif (add_WR_CE = '1') then |
add_WR <= n_add_WR; |
add_WR_GC <= iadd_WR_GC; |
else |
add_WR <= add_WR; |
add_WR_GC <= add_WR_GC; |
end if; |
end if; |
end process; |
|
full <= ifull; |
|
ifull <= '0' when (iempty = '1') else -- just in case add_RD_WS is reset to all zero's |
'0' when (add_RD_WS /= add_WR_GC) else ---- instend of "11 zero's" |
'1'; |
|
|
----------------------------------------- |
----- Read address counter -------------- |
----------------------------------------- |
|
|
add_RD_CE <= '0' when (iempty = '1') else |
'0' when (RD = '0') else |
'1'; |
|
n_add_RD <= add_RD + "01"; |
|
U2 : gh_binary2gray |
generic map (size => 5) |
port map( |
B => n_add_RD, |
G => iadd_RD_GC -- to be used for empty flag |
); |
|
iiadd_RD_GCwc <= (not n_add_RD(4)) & n_add_RD(3 downto 0); |
|
U3 : gh_binary2gray |
generic map (size => 5) |
port map( |
B => iiadd_RD_GCwc, |
G => iadd_RD_GCwc -- to be used for full flag |
); |
|
process (clk_RD,rst) |
begin |
if (rst = '1') then |
add_RD <= (others => '0'); |
add_WR_RS <= (others => '0'); |
add_RD_GC <= (others => '0'); |
add_RD_GCwc(4 downto 3) <= "11"; |
add_RD_GCwc(2 downto 0) <= (others => '0'); |
diempty <= '1'; |
elsif (rising_edge(clk_RD)) then |
add_WR_RS <= add_WR_GC; |
diempty <= iempty; |
if (srst_r = '1') then |
add_RD <= (others => '0'); |
add_RD_GC <= (others => '0'); |
add_RD_GCwc(4 downto 3) <= "11"; |
add_RD_GCwc(2 downto 0) <= (others => '0'); |
elsif (add_RD_CE = '1') then |
add_RD <= n_add_RD; |
add_RD_GC <= iadd_RD_GC; |
add_RD_GCwc <= iadd_RD_GCwc; |
else |
add_RD <= add_RD; |
add_RD_GC <= add_RD_GC; |
add_RD_GCwc <= add_RD_GCwc; |
end if; |
end if; |
end process; |
|
empty <= diempty; |
|
iempty <= '1' when (add_WR_RS = add_RD_GC) else |
'0'; |
|
U4 : gh_gray2binary |
generic map (size => 5) |
port map( |
G => add_RD_GC, |
B => c_add_RD |
); |
|
U5 : gh_gray2binary |
generic map (size => 5) |
port map( |
G => add_WR_RS, |
B => c_add_WR |
); |
|
c_add <= (c_add_WR - c_add_RD); |
|
q_full <= '0' when (iempty = '1') else |
'0' when (c_add(4 downto 2) = "000") else |
'1'; |
|
h_full <= '0' when (iempty = '1') else |
'0' when (c_add(4 downto 3) = "00") else |
'1'; |
|
a_full <= '0' when (iempty = '1') else |
'0' when (c_add(4 downto 1) < "0111") else |
'1'; |
|
---------------------------------- |
--- sync rest stuff -------------- |
--- rc_srst is sync with clk_RD -- |
--- srst_w is sync with clk_WR --- |
---------------------------------- |
|
process (clk_WR,rst) |
begin |
if (rst = '1') then |
srst_w <= '0'; |
isrst_r <= '0'; |
elsif (rising_edge(clk_WR)) then |
srst_w <= isrst_w; |
if (srst_w = '1') then |
isrst_r <= '1'; |
elsif (srst_w = '0') then |
isrst_r <= '0'; |
end if; |
end if; |
end process; |
|
process (clk_RD,rst) |
begin |
if (rst = '1') then |
srst_r <= '0'; |
isrst_w <= '0'; |
elsif (rising_edge(clk_RD)) then |
srst_r <= rc_srst; |
if (rc_srst = '1') then |
isrst_w <= '1'; |
elsif (isrst_r = '1') then |
isrst_w <= '0'; |
end if; |
end if; |
end process; |
|
end architecture; |
/gh_uart_Tx_8bit.vhd
0,0 → 1,292
----------------------------------------------------------------------------- |
-- Filename: gh_uart_Tx_8bit.vhd |
-- |
-- Description: |
-- an 8 bit UART Tx Module |
-- |
-- Copyright (c) 2006, 2007 by H LeFevre |
-- A VHDL 16550 UART core |
-- an OpenCores.org Project |
-- free to use, but see documentation for conditions |
-- |
-- Revision History: |
-- Revision Date Author Comment |
-- -------- ---------- --------- ----------- |
-- 1.0 02/18/06 H LeFevre Initial revision |
-- 1.1 02/25/06 H LeFevre add BUSYn output |
-- 2.0 06/18/07 P.Azkarate Define "range" in T_WCOUNT and x_dCOUNT signals |
-- 2.1 07/12/07 H LeFevre fix a problem with 5 bit data and 1.5 stop bits |
-- as pointed out by Matthias Klemm |
-- 2.2 08/17/07 H LeFevre add stopB to sensitivity list line 164 |
-- as suggested by Guillaume Zin |
----------------------------------------------------------------------------- |
library ieee ; |
use ieee.std_logic_1164.all ; |
|
entity gh_uart_Tx_8bit is |
port( |
clk : in std_logic; -- clock |
rst : in std_logic; |
xBRC : in std_logic; -- x clock enable |
D_RYn : in std_logic; -- data ready |
D : in std_logic_vector(7 downto 0); |
num_bits : in integer:= 8; -- number of bits in transfer |
Break_CB : in std_logic; |
stopB : in std_logic; |
Parity_EN : in std_logic; |
Parity_EV : in std_logic; |
sTX : out std_logic; |
BUSYn : out std_logic; |
read : out std_logic -- data read |
); |
end entity; |
|
architecture a of gh_uart_Tx_8bit is |
|
COMPONENT gh_shift_reg_PL_sl is |
GENERIC (size: INTEGER := 16); |
PORT( |
clk : IN STD_logic; |
rst : IN STD_logic; |
LOAD : IN STD_LOGIC; -- load data |
SE : IN STD_LOGIC; -- shift enable |
D : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0); |
Q : OUT STD_LOGIC_VECTOR(size-1 DOWNTO 0) |
); |
END COMPONENT; |
|
COMPONENT gh_parity_gen_Serial is |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
srst : in STD_LOGIC; |
SD : in STD_LOGIC; -- sample data pulse |
D : in STD_LOGIC; -- data |
Q : out STD_LOGIC |
); |
END COMPONENT; |
|
COMPONENT gh_counter_integer_down IS |
generic(max_count : integer := 8); |
PORT( |
clk : IN STD_LOGIC; |
rst : IN STD_LOGIC; |
LOAD : in STD_LOGIC; -- load D |
CE : IN STD_LOGIC; -- count enable |
D : in integer RANGE 0 TO max_count; |
Q : out integer RANGE 0 TO max_count |
); |
END COMPONENT; |
|
type T_StateType is (idle,s_start_bit,shift_data,s_parity, |
s_stop_bit,s_stop_bit2); |
signal T_state, T_nstate : T_StateType; |
|
signal parity : std_logic; |
signal parity_Grst : std_logic; |
signal TWC_LD : std_logic; |
signal TWC_CE : std_logic; |
signal T_WCOUNT : integer range 0 to 15; |
signal D_LD_v : integer range 1 to 15; |
signal D_LD : std_logic; |
signal Trans_sr_SE : std_logic; |
signal Trans_shift_reg : std_logic_vector(7 downto 0); |
signal iTX : std_logic; |
signal BRC : std_logic; |
signal dCLK_LD : std_logic; |
signal x_dCOUNT : integer range 0 to 15; |
|
begin |
|
---------------------------------------------- |
---- outputs---------------------------------- |
---------------------------------------------- |
|
BUSYn <= '1' when (T_state = idle) else |
'0'; |
|
read <= D_LD; -- read a data word |
|
---------------------------------------------- |
|
dCLK_LD <= '1' when ((num_bits = 5) and (stopB = '1') |
and (T_state = s_stop_bit2) and (x_dCOUNT = 7)) else |
'0' when (D_RYn = '0') else |
'0' when (T_state /= idle) else |
'1'; |
|
D_LD_v <= 15 when (T_state = s_stop_bit2) else |
1; |
|
BRC <= '0' when (xBRC = '0') else |
'1' when (x_dCOUNT = 0) else |
'0'; |
|
|
u1 : gh_counter_integer_down -- baud rate divider |
generic map (15) |
port map( |
clk => clk, |
rst => rst, |
LOAD => dCLK_LD, |
CE => xBRC, |
D => D_LD_v, |
Q => x_dCOUNT); |
|
U2 : gh_shift_reg_PL_sl |
Generic Map(8) |
PORT MAP ( |
clk => clk, |
rst => rst, |
LOAD => D_LD, |
SE => Trans_sr_SE, |
D => D, |
Q => Trans_shift_reg); |
|
-------------------------------------------------------------- |
-------------------------------------------------------------- |
|
process (clk,rst) |
begin |
if (rst = '1') then |
sTX <= '1'; |
elsif (rising_edge(clk)) then |
sTX <= iTX and (not Break_CB); |
end if; |
end process ; |
|
iTX <= '0' when (T_state = s_start_bit) else -- send start bit |
Trans_shift_reg(0) when (T_state = shift_data) else -- send data |
parity when ((Parity_EV = '1') and (T_state = s_parity)) else |
(not parity) when (T_state = s_parity) else |
'1'; -- idle, stop bit |
|
process(T_state,D_RYn,BRC,T_WCOUNT,Parity_EN,num_bits,x_dCOUNT,stopB) |
begin |
case T_state is |
when idle => -- idle |
TWC_CE <= '0'; |
if ((D_RYn = '0') and (BRC = '1')) then |
D_LD <= '1'; Trans_sr_SE <= '0'; |
TWC_LD <= '0'; |
T_nstate <= s_start_bit; |
else |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= idle; |
end if; |
when s_start_bit => -- fifo is read, send start bit |
TWC_CE <= '0'; |
if (BRC = '1') then |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '1'; |
T_nstate <= shift_data; |
else |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_start_bit; |
end if; |
when shift_data => -- send data bit |
if (BRC = '0') then |
D_LD <= '0'; Trans_sr_SE <= '0'; |
TWC_LD <= '0'; TWC_CE <= '0'; |
T_nstate <= shift_data; |
elsif ((T_WCOUNT = 1) and (Parity_EN = '1')) then |
D_LD <= '0'; Trans_sr_SE <= '0'; |
TWC_LD <= '0'; TWC_CE <= '1'; |
T_nstate <= s_parity; |
elsif (T_WCOUNT = 1) then |
D_LD <= '0'; Trans_sr_SE <= '0'; |
TWC_LD <= '0'; TWC_CE <= '1'; |
T_nstate <= s_stop_bit; |
else |
D_LD <= '0'; Trans_sr_SE <= '1'; |
TWC_LD <= '0'; TWC_CE <= '1'; |
T_nstate <= shift_data; |
end if; |
when s_parity => -- send parity bit |
TWC_CE <= '0'; |
if (BRC = '1') then |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_stop_bit; |
else |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_parity; |
end if; |
when s_stop_bit => -- send stop bit |
TWC_CE <= '0'; |
if (BRC = '0') then |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_stop_bit; |
elsif (stopB = '1') then |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_stop_bit2; |
elsif (D_RYn = '0') then |
D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_start_bit; |
else |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= idle; |
end if; |
when s_stop_bit2 => -- send stop bit |
TWC_CE <= '0'; |
if ((D_RYn = '0') and (BRC = '1')) then |
D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_start_bit; |
elsif (BRC = '1') then |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= idle; |
elsif ((num_bits = 5) and (x_dCOUNT = 7) and (D_RYn = '0')) then |
D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_start_bit; |
elsif ((num_bits = 5) and (x_dCOUNT = 7)) then |
D_LD <= '1'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= idle; |
else |
D_LD <= '0'; Trans_sr_SE <= '0'; TWC_LD <= '0'; |
T_nstate <= s_stop_bit2; |
end if; |
when others => |
D_LD <= '0'; Trans_sr_SE <= '0'; |
TWC_LD <= '0'; TWC_CE <= '0'; |
T_nstate <= idle; |
end case; |
end process; |
|
-- |
-- registers for SM |
process(CLK,rst) |
begin |
if (rst = '1') then |
T_state <= idle; |
elsif (rising_edge(CLK)) then |
T_state <= T_nstate; |
end if; |
end process; |
|
u3 : gh_counter_integer_down -- word counter |
generic map (8) |
port map( |
clk => clk, |
rst => rst, |
LOAD => TWC_LD, |
CE => TWC_CE, |
D => num_bits, |
Q => T_WCOUNT |
); |
|
-------------------------------------------------------- |
-------------------------------------------------------- |
|
parity_Grst <= '1' when (T_state = s_start_bit) else |
'0'; |
|
U4 : gh_parity_gen_Serial |
PORT MAP ( |
clk => clk, |
rst => rst, |
srst => parity_Grst, |
SD => BRC, |
D => Trans_shift_reg(0), |
Q => parity); |
|
|
end a; |
|
/ab_register_rx_handler.vhd
0,0 → 1,242
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- -- |
-- -- |
------------------------------------------------------------------------------- |
-- |
-- unit name: register_rx_handler |
-- |
-- author: Mauro Predonzani (mauro.predonzani@elettra.trieste.it) |
-- Andrea Borga (andrea.borga@nikhef.nl) |
-- |
-- date: 20/02/2009 $: created |
-- |
-- version: $Rev 1.0 $: |
-- |
-- description: |
-- |
-- the module acquires byte |
-- and decodes the data as follows: |
-- |
-- ----------------------------------------------------- |
-- | ADDRESS | DATA | |
-- ----------------------------------------------------- |
-- | 15-08 | 07-00 | 31-24 | 23-16 | 15-08 |07-00 | |
-- | reghnd_full_add | reghnd_full_data | |
-- ----------------------------------------------------- |
-- BYTE NUM | BYTEO | BYTE1 | BYTE2 | BYTE3 | BYTE4 | BYTE5 | |
-- ----------------------------------------------------- |
-- |
-- number of register cells: 2^16 |
-- data word lenght: 32 bits |
-- |
-- |
-- dependencies: Lantronix_wrapper |
-- uart_lbus_slave |
-- gh_uart_16550 |
-- |
-- references: <reference one> |
-- <reference two> ... |
-- |
-- modified by: $Author:: $: |
-- 04-08-2011 Andrea Borga |
-- missing s_tick reset value |
-- 18-08-2011 Andrea Borga |
-- removed unused vraious v_registers |
-- |
------------------------------------------------------------------------------- |
-- last changes: <date> <initials> <log> |
-- <extended description> |
------------------------------------------------------------------------------- |
-- TODO: |
-- |
-- |
-- |
-- |
------------------------------------------------------------------------------- |
|
--============================================================================= |
-- Libraries |
--============================================================================= |
|
library ieee ; |
use ieee.std_logic_1164.all ; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
--============================================================================= |
-- Entity declaration for ada_register_handler |
--============================================================================= |
|
entity register_rx_handler is |
port( |
reghnd_clk : in std_logic; -- system clock |
reghnd_rst : in std_logic; -- system reset |
reghnd_data_in : in std_logic_vector(7 downto 0); -- 8 bits fragments |
reghnd_data_cs_rd : in std_logic; -- cs strobe of gh16550 during a read process |
reghnd_data_wr_rd : in std_logic; -- wr state of gh16550 during a read process |
reghnd_rd_rdy : out std_logic; -- Read data ready |
reghnd_full_add : out std_logic_vector(15 downto 0); -- 16 bits RAM address |
reghnd_full_data : out std_logic_vector(31 downto 0); -- 32 bits RAM data |
reghnd_full_cs : in std_logic -- strobe data/address acquired (1 acquired - 0 not acquired) |
); |
end entity; |
|
--============================================================================= |
-- architecture declaration |
--============================================================================= |
|
architecture a of register_rx_handler is |
|
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-- Components declaration |
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
-- |
-- Internal signal declaration |
-- |
|
signal s_rst : std_logic; -- global reset |
signal s_clk : std_logic; -- uart to parallel interface clock |
|
signal s_read_mem : std_logic; -- read data from memory |
|
signal s_write_mem : std_logic; -- write data into memory |
signal v_wr_add : std_logic_vector(15 downto 0); -- full write ADDRESS |
signal v_wr_data : std_logic_vector(31 downto 0); -- full write DATA |
|
signal s_tick : std_logic; |
|
-- |
-- State Machine states |
-- |
|
type t_reg_decoder is (IDLE, BYTE0, BYTE1, BYTE2, BYTE3, BYTE4, BYTE5, WRITE_MEM); |
signal s_reg_decoder : t_reg_decoder; |
|
--============================================================================= |
-- architecture begin |
--============================================================================= |
|
begin |
|
s_rst <= reghnd_rst; |
s_clk <= reghnd_clk; |
reghnd_rd_rdy <= s_write_mem; |
|
p_register_decoder : process(s_rst, s_clk) |
begin |
if s_rst = '1' then -- reset |
s_write_mem <= '0'; |
reghnd_full_add <= (others => '0'); |
reghnd_full_data <= (others => '0'); |
v_wr_add <= (others => '0'); |
v_wr_data <= (others => '0'); |
s_tick <= '0'; |
s_reg_decoder <= IDLE; |
elsif Rising_edge(s_clk) then |
case s_reg_decoder is |
when IDLE => -- IDLE state |
s_write_mem <= '0'; |
reghnd_full_add <= (others => '0'); |
reghnd_full_data <= (others => '0'); |
v_wr_add <= (others => '0'); |
v_wr_data <= (others => '0'); |
if reghnd_data_cs_rd = '1' and reghnd_data_wr_rd = '0' then -- check if BYTE0 is ready |
s_reg_decoder <= BYTE0; |
else |
s_reg_decoder <= IDLE; |
s_tick <= '0'; |
end if; |
when BYTE0 => -- decode byte 0 ADDRESS upper |
s_write_mem <= '0'; |
if s_tick = '0' then -- only first time in this cycle acq the byte |
v_wr_add (15 downto 8) <= reghnd_data_in; |
s_tick <= '1'; |
elsif reghnd_data_cs_rd = '1' and reghnd_data_wr_rd = '0' then -- check if BYTE1 is ready |
s_reg_decoder <= BYTE1; |
s_tick <= '0'; |
else |
s_reg_decoder <= BYTE0; |
s_tick <= '1'; |
end if; |
when BYTE1 => -- decode byte 1 ADDRESS lower |
s_write_mem <= '0'; |
if s_tick = '0' then -- only first time in this cycle acq the byte |
v_wr_add (7 downto 0) <= reghnd_data_in; |
s_tick <= '1'; |
elsif reghnd_data_cs_rd = '1' and reghnd_data_wr_rd = '0' then -- check if BYTE2 is ready |
s_reg_decoder <= BYTE2; |
s_tick <= '0'; |
else |
s_reg_decoder <= BYTE1; |
s_tick <= '1'; |
end if; |
when BYTE2 => -- decode byte 2 = DATA1 |
s_write_mem <= '0'; |
if s_tick = '0' then -- only first time in this cycle acq the byte |
v_wr_data (31 downto 24) <= reghnd_data_in; |
s_tick <= '1'; |
elsif reghnd_data_cs_rd = '1' and reghnd_data_wr_rd = '0' then -- check if BYTE3 is ready |
s_reg_decoder <= BYTE3; |
s_tick <= '0'; |
else |
s_reg_decoder <= BYTE2; |
s_tick <= '1'; |
end if; |
when BYTE3 => -- decode byte 3 = DATA2 |
s_write_mem <= '0'; |
if s_tick = '0' then -- only first time in this cycle acq the byte |
v_wr_data (23 downto 16) <= reghnd_data_in; |
s_tick <= '1'; |
elsif reghnd_data_cs_rd = '1' and reghnd_data_wr_rd = '0' then -- check if BYTE4 is ready |
s_reg_decoder <= BYTE4; |
s_tick <= '0'; |
else |
s_reg_decoder <= BYTE3; |
s_tick <= '1'; |
end if; |
when BYTE4 => -- decode byte 4 = DATA3 |
s_write_mem <= '0'; |
if s_tick = '0' then -- only first time in this cycle acq the byte |
v_wr_data (15 downto 8) <= reghnd_data_in; |
s_tick <= '1'; |
elsif reghnd_data_cs_rd = '1' and reghnd_data_wr_rd = '0' then -- check if BYTE5 is ready |
s_reg_decoder <= BYTE5; |
s_tick <= '0'; |
else |
s_reg_decoder <= BYTE4; |
s_tick <= '1'; |
end if; |
when BYTE5 => -- decode byte 5 = DATA4 |
s_write_mem <= '0'; |
if s_tick = '0' then -- only first time in this cycle acq the byte |
v_wr_data (7 downto 0) <= reghnd_data_in; |
s_tick <= '1'; |
else -- add and data are ready => ready to use |
s_reg_decoder <= WRITE_MEM; |
s_tick <= '0'; |
reghnd_full_add <= v_wr_add; -- address latch to the ouput |
reghnd_full_data <= v_wr_data; -- data latch to the output |
end if; |
when WRITE_MEM => -- write data into RAM |
s_write_mem <= '1'; -- data and address stable and ready |
if reghnd_full_cs = '1' then -- check if data is transfer to RAM or not |
s_reg_decoder <= IDLE; |
else |
s_reg_decoder <= WRITE_MEM; |
end if; |
when others => |
s_reg_decoder <= IDLE; |
end case; |
end if; |
end process p_register_decoder; |
|
|
end a; |
|
--============================================================================= |
-- architecture end |
--============================================================================= |
/ab_uart_lbus_slave.vhd
0,0 → 1,438
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- -- |
-- -- |
------------------------------------------------------------------------------- |
-- |
-- unit name: uart_lbus (UART Control) |
-- |
-- author: Andrea Borga (andrea.borga@nikhef.nl) |
-- Mauro Predonzani (mauro.predonzani@elettra.trieste.it) |
-- |
-- date: $26/01/2009 $: created |
-- |
-- version: $Rev 0 $: |
-- |
-- description: <file content, behaviour, purpose, special usage notes...> |
-- <further description> |
-- |
-- dependencies: Lantronix_wrapper |
-- gh_uart_16550 |
-- register_rx_handler |
-- register_tx_handler |
-- |
-- references: <reference one> |
-- <reference two> ... |
-- |
-- modified by: $Author:: $: |
-- 18/08/2011 Andrea Borga |
-- modified UART_WRITE to improve stability |
-- |
------------------------------------------------------------------------------- |
-- last changes: <date> <initials> <log> |
-- <extended description> |
------------------------------------------------------------------------------- |
-- TODO: |
-- check the address range (range violation prevention) |
-- |
-- |
------------------------------------------------------------------------------- |
|
--============================================================================= |
-- Libraries |
--============================================================================= |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
--============================================================================= |
-- Entity declaration for ada_uart_lbus |
--============================================================================= |
|
entity uart_lbus is |
generic ( |
c_bus_width : natural := 8 |
); |
port ( |
lbus_clk : in std_logic; -- local bus clock |
lbus_rst : in std_logic; -- local bus reset |
lbus_rst_buffer : out std_logic; -- soft reset for UART fifos |
lbus_txrdy_n : in std_logic; -- Tx data ready |
lbus_rxrdy_n : in std_logic; -- Rx data ready |
lbus_cs : out std_logic; -- Chip Select |
lbus_wr : out std_logic; -- Write/Read (1/0) |
lbus_init : out std_logic; -- Initialization process flag |
lbus_add : out std_logic_vector(2 downto 0); -- local bus address |
lbus_data : out std_logic_vector(c_bus_width-1 downto 0); -- local bus data |
s_tx_proc_rqst_i : in std_logic; -- tx process request from RAM |
v_lbus_state : out std_logic_vector(2 downto 0); -- flag indicator of lbus_state |
s_cs_rd_c : out std_logic; -- CS signal from caused by read cycle |
s_wr_rd_c : out std_logic; -- WR signal from caused by read cycle |
s_new_byte_rdy : in std_logic; -- new byte(8bit) is ready and stable to be transmitted |
s_data_tx : in std_logic; -- trasmitting byte of RAM address/data |
reghnd_rd_rdy : in std_logic; -- 6 byte ready RX but not yet written in RAM (1/0=>data ready/not ready) |
echo_en_i : in std_logic -- echo enable command enable/disable = 1/0 |
|
); |
end uart_lbus; |
|
|
--============================================================================= |
-- architecture declaration |
--============================================================================= |
|
architecture slave of uart_lbus is |
|
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-- Components declaration |
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
-- component gh_edge_det is |
-- port( |
-- clk : in std_logic; |
-- rst : in std_logic; |
-- d : in std_logic; |
-- re : out std_logic; -- rising edge (need sync source at d) |
-- fe : out std_logic; -- falling edge (need sync source at d) |
-- sre : out std_logic; -- sync'd rising edge |
-- sfe : out std_logic -- sync'd falling edge |
-- ); |
-- end component; |
|
-- |
-- Internal signal declaration |
-- |
|
signal v_data_gen : std_logic_vector(7 downto 0); -- test data generator |
signal s_data_toggle : std_logic; -- toggles between two data patterns AA and 55 |
signal v_data_num : std_logic_vector(19 downto 0); -- number of data to send |
|
signal s_wr_rd : std_logic; -- wr for READ state process |
signal v_add_rd : std_logic_vector(2 downto 0); |
|
signal s_tx_term : std_logic; -- transmission teminating strobe |
signal s_tx_send_data : std_logic; -- data to send strobe |
signal s_cs_wr : std_logic; -- cs for WRITE state process |
signal s_wr_wr : std_logic; -- wr for WRITE state process |
signal v_add_wr : std_logic_vector(2 downto 0); |
|
signal v_add : std_logic_vector(2 downto 0); |
signal v_data : std_logic_vector(c_bus_width-1 downto 0); |
|
signal s_init_done : std_logic; -- initialization done flag |
signal s_write_msb : std_logic; |
signal s_tick_delay : std_logic; -- delays termination by 1 cycle (needed for lbus init) |
signal v_tick_delay_1 : std_logic_vector(1 downto 0); -- delays termination by 1 cycle (needed for RW_lbus) |
signal s_cs_init : std_logic; -- cs for INIT state process |
signal s_wr_init : std_logic; -- wr for INIT state process |
signal v_add_init : std_logic_vector(2 downto 0); |
signal v_data_init : std_logic_vector(c_bus_width-1 downto 0); |
signal v_fcr_init : std_logic_vector(7 downto 0); -- local FIFO Control Register O"2" |
signal v_lcr_init : std_logic_vector(7 downto 0); -- local Line Control Register O"3" |
signal v_lsr_init : std_logic_vector(7 downto 0); -- local Line Status Register O"5" |
signal s_cs_rd : std_logic; |
-- |
-- State Machine states |
-- |
|
type t_uart_state is (IDLE, INIT, UART_READ, UART_WRITE); |
signal s_slave_state : t_uart_state; |
|
type t_uart_init is (IDLE, WRITE_FCR, WRITE_LCR, WRITE_DIVLTC, ENB_FIFO, ENB_UART); |
signal s_slave_init : t_uart_init; |
|
--============================================================================= |
-- architecture begin |
--============================================================================= |
|
|
signal lbus_clk_n : std_logic; |
|
|
begin |
|
-- |
-- Internal signals |
-- |
|
lbus_clk_n <= not lbus_clk; |
s_cs_rd_c <= s_cs_rd; |
s_wr_rd_c <= s_wr_rd; |
lbus_add <= v_add_init or v_add_wr or v_add_rd; |
lbus_data <= v_data_init; -- or v_data_wr; |
lbus_init <= not s_init_done; -- init signal |
|
lbus_cs <= s_cs_init or s_cs_wr or s_cs_rd; -- CS uart signal |
lbus_wr <= s_wr_init or s_wr_wr or s_wr_rd; -- R/W control UART signal |
|
|
|
|
--************************************************************************** |
-- UART local bus slave |
-- (state transitions) |
--************************************************************************** |
-- read: lbus_clk |
-- write: |
-- r/w: s_slave_state |
|
p_uart_state: process (lbus_clk_n) |
begin |
if Rising_edge(lbus_clk_n) then |
if lbus_rst = '1' then -- Sync RESET |
s_slave_state <= IDLE; |
s_cs_wr <= '0'; |
s_wr_wr <= '0'; |
s_cs_rd <= '0'; |
s_wr_rd <= '0'; |
v_add_wr <= (others => '0'); |
v_add_rd <= (others => '0'); |
v_tick_delay_1 <= "00"; |
v_lbus_state <= "000"; |
lbus_rst_buffer <= '1'; -- rest UART FIFO |
else |
case s_slave_state is |
when IDLE => -- uart IDLE |
s_cs_rd <= '0'; |
s_wr_rd <= '0'; |
s_cs_wr <= '0'; |
s_wr_wr <= '0'; |
v_tick_delay_1 <= "00"; |
if s_init_done = '0' then |
s_slave_state <= INIT; |
v_lbus_state <= "001"; |
else |
lbus_rst_buffer <= '0'; -- release UART FIFO after init |
if s_tx_proc_rqst_i = '1' and lbus_txrdy_n = '0' then -- and reghnd_rd_rdy = '0' then |
v_lbus_state <= "100"; |
s_slave_state <= UART_WRITE; |
elsif s_tx_proc_rqst_i = '0' and lbus_rxrdy_n = '0' and lbus_txrdy_n = '0' and reghnd_rd_rdy = '0' then |
s_slave_state <= UART_READ; |
v_lbus_state <= "010"; |
else |
s_slave_state <= IDLE; |
v_lbus_state <= "000"; |
end if; |
end if; |
when INIT => -- uart INIT |
v_lbus_state <= "001"; |
if s_init_done = '0' then |
s_slave_state <= INIT; |
else |
s_slave_state <= IDLE; |
end if; |
when UART_READ => -- uart READ |
v_lbus_state <= "010"; |
s_cs_wr <= '0'; |
s_wr_wr <= '0'; |
if lbus_rxrdy_n = '0' then |
if v_tick_delay_1 = "00" then |
if echo_en_i = '1' then -- ECHO is enable |
v_tick_delay_1 <= "01"; |
elsif echo_en_i = '0' then -- ECHO is disable |
v_tick_delay_1 <= "11"; |
end if; |
s_cs_rd <= '1'; |
s_wr_rd <= '0'; |
s_slave_state <= UART_READ; |
elsif v_tick_delay_1 = "01" then -- will be executed in a READ cycle only if ECHO is enable |
v_tick_delay_1 <= "10"; |
v_add_rd <= O"0"; |
s_cs_rd <= '0'; |
s_wr_rd <= '1'; |
s_slave_state <= UART_READ; |
elsif v_tick_delay_1 = "10" then -- will be executed in a READ cycle only if ECHO is enable |
v_tick_delay_1 <= "11"; |
v_add_rd <= O"0"; |
s_cs_rd <= '1'; |
s_wr_rd <= '1'; |
s_slave_state <= UART_READ; |
elsif v_tick_delay_1 = "11" then -- will be executed in every READ cycle |
v_tick_delay_1 <= "00"; |
v_add_rd <= O"0"; |
s_cs_rd <= '0'; |
s_wr_rd <= '0'; |
s_slave_state <= IDLE; |
end if; |
else |
s_cs_rd <= '0'; |
s_wr_rd <= '0'; |
s_slave_state <= IDLE; |
end if; |
when UART_WRITE => -- uart WRITE |
v_lbus_state <= "100"; |
if v_tick_delay_1 = "00" then |
if s_new_byte_rdy = '1' then |
v_tick_delay_1 <= "01"; |
s_cs_wr <= '0'; |
s_wr_wr <= '1'; |
else |
v_tick_delay_1 <= "00"; |
if s_tx_proc_rqst_i = '0' and s_data_tx = '0' then |
s_slave_state <= IDLE; |
else |
s_slave_state <= UART_WRITE; |
end if; |
end if; |
elsif v_tick_delay_1 ="01" then |
v_tick_delay_1 <= "11"; |
s_cs_wr <= '1'; |
s_wr_wr <= '1'; |
v_add_wr <= O"0"; |
s_slave_state <= UART_WRITE; |
elsif v_tick_delay_1 ="11" then |
if s_new_byte_rdy = '1' then |
v_tick_delay_1 <= "11"; |
s_cs_wr <= '0'; |
s_wr_wr <= '1'; |
v_add_wr <= O"0"; |
s_slave_state <= UART_WRITE; |
else |
v_tick_delay_1 <= "00"; |
s_cs_wr <= '0'; |
s_wr_wr <= '1'; |
v_add_wr <= O"0"; |
s_slave_state <= UART_WRITE; |
end if; |
else |
s_cs_rd <= '0'; |
s_wr_rd <= '0'; |
s_slave_state <= IDLE; |
end if; |
when others => -- uart OTHERS |
s_slave_state <= IDLE; |
end case; |
end if; |
end if; |
end process p_uart_state; |
|
--************************************************************************** |
-- UART local bus slave |
-- (initialization) |
--************************************************************************** |
-- read: |
-- write: |
-- r/w: |
|
p_init_lbus : process (lbus_clk, lbus_rst) -- uart initialization process |
begin -- process |
if lbus_rst = '1' then |
s_slave_init <= IDLE; |
v_add_init <= O"7"; |
v_data_init <= (others => '0'); |
v_lcr_init <= (others => '0'); |
v_fcr_init <= (others => '0'); |
s_tick_delay <= '0'; |
s_write_msb <= '0'; |
s_cs_init <= '0'; |
s_wr_init <= '0'; |
s_init_done <= '0'; |
elsif Rising_edge(lbus_clk) then |
case s_slave_init is |
when IDLE => -- init IDLE |
if s_init_done = '0' and s_write_msb = '0' then |
s_cs_init <= '1'; |
s_wr_init <= '1'; |
s_slave_init <= WRITE_FCR; |
else |
s_slave_init <= IDLE; |
end if; |
when WRITE_FCR => -- init WRITE_FCR |
v_add_init <= O"2"; |
v_fcr_init <= "00000000"; -- DMA mode 0 init FIFO Control Register |
v_data_init <= "00000000"; -- DMA mode 0 write FIFO Control Register |
-- v_fcr_init <= "00001000"; -- DMA mode 1 init FIFO Control Register |
-- v_data_init <= "00001000"; -- DMA mode 1 write FIFO Control Register |
s_slave_init <= WRITE_LCR; |
when WRITE_LCR => -- init WRITE_LCR |
v_add_init <= O"3"; |
v_lcr_init <= "10000011"; -- init FIFO Control Register |
v_data_init <= "10000011"; -- write FIFO Control Register |
s_slave_init <= WRITE_DIVLTC; |
when WRITE_DIVLTC => -- init WRITE_DIVLTC |
if s_write_msb = '0' then |
v_add_init <= O"0"; -- init Divisor Latch lsb |
v_data_init <= "00000010";--"00001111"; -- DEC 15 Baudrate = 230400 bps @ 55,296 MHz |
s_write_msb <= '1'; |
s_slave_init <= WRITE_DIVLTC; |
else |
v_add_init <= O"1"; -- init Divisor Latch msb |
v_data_init <= "00000000"; |
s_slave_init <= ENB_FIFO; |
end if; |
when ENB_FIFO => -- init ENB_FIFO |
if s_tick_delay = '0' then |
s_tick_delay <= '1'; |
v_add_init <= O"3"; |
v_lcr_init <= "00000011"; -- Enable FIFO access |
v_data_init <= "00000011"; |
else |
v_add_init <= (others => '0'); |
v_data_init <= (others => '0'); |
s_tick_delay <= '0'; |
s_slave_init <= ENB_UART; |
end if; |
when ENB_UART => -- init ENB_UART |
if s_tick_delay = '0' then |
s_tick_delay <= '1'; |
s_init_done <= '1'; -- terminate init |
s_cs_init <= '0'; |
s_wr_init <= '0'; |
v_data_init <= "00000000"; |
else |
s_tick_delay <= '0'; |
s_init_done <= '1'; |
s_slave_init <= IDLE; |
end if; |
when others => |
s_slave_init <= IDLE; |
end case; |
end if; |
end process; |
|
|
|
|
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-- Components mapping |
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
-- cmp_cs_rd_edge : gh_edge_det |
-- port map ( |
-- clk => lbus_clk, |
-- rst => lbus_rst, |
-- d => s_cs_rd, |
-- sre => s_cs_rd_edge); |
|
-- cmp_wr_rd_edge : gh_edge_det |
-- port map ( |
-- clk => lbus_clk, |
-- rst => lbus_rst, |
-- d => s_wr_rd, |
-- sre => s_wr_rd_edge); |
|
-- cmp_cs_wr_edge : gh_edge_det |
-- port map ( |
-- clk => lbus_clk, |
-- rst => lbus_rst, |
-- d => s_cs_wr, |
-- sre => s_cs_wr_edge); |
-- |
-- cmp_wr_wr_edge : gh_edge_det |
-- port map ( |
-- clk => lbus_clk, |
-- rst => lbus_rst, |
-- d => s_wr_wr, |
-- sre => s_wr_wr_edge); |
|
end slave; |
|
--============================================================================= |
-- architecture end |
--============================================================================= |
|
|
/ab_uart_16550_wrapper.vhd
0,0 → 1,570
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- -- |
-- -- |
------------------------------------------------------------------------------- |
-- |
-- unit name: UART_16550_wrapper |
-- |
-- author: Andrea Borga (andrea.borga@nikhef.it) |
-- Mauro Predonzani (mauro.predonzani@elettra.trieste.it) |
-- |
-- date: $26/01/2009 $: created |
-- |
-- version: $Rev 0 $: |
-- |
-- description: <file content, behaviour, purpose, special usage notes...> |
-- <further description> |
-- |
-- dependencies: gh_uart_16550 |
-- register_rx_handler |
-- register_tx_handler |
-- uart_lbus_slave |
-- |
-- |
-- |
-- references: <reference one> |
-- <reference two> ... |
-- |
-- modified by: $Author:: $: |
-- |
------------------------------------------------------------------------------- |
-- changes: 2010-05-06 Mauro Predonzani |
-- set ECHO MODE on/off |
-- 2010-06-09 Mauro Predonzani |
-- enable/disable TX address byte |
-- 2011-08-18 Andrea Borga |
-- added soft FIFO reset release after init |
-- 2011-08-18 Andrea Borga |
-- renamed entity to a more generic UART_16550_wrapper |
-- (instead of Lantronix_wrapper) |
-- <extended description> |
------------------------------------------------------------------------------- |
-- TODO: |
-- |
-- |
-- |
------------------------------------------------------------------------------- |
|
--============================================================================= |
-- Libraries |
--============================================================================= |
|
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
|
--============================================================================= |
-- Entity declaration for ada_uart_16550_wrapper |
--============================================================================= |
|
entity uart_16550_wrapper is |
port( |
-- general purpose |
sys_clk_i : in std_logic; -- system clock |
sys_rst_i : in std_logic; -- system reset |
-- TX/RX process command line |
echo_en_i : in std_logic; -- Echo enable (byte by byte) enable/disable = 1/0 |
tx_addr_wwo_i : in std_logic; -- control of TX process With or WithOut address W/WO=(1/0) |
-- serial I/O side |
lantronix_output_i : in std_logic; -- Lantronix Serial data OUTPUT signal |
lantronix_input_o : out std_logic; -- Lantronix Serial data INPUT signal |
cp_b : inout std_logic_vector(2 downto 0); -- general purpose IO pins |
-- parallel I/O side |
s_br_clk_uart_o : out std_logic; -- br_clk clock probe signal |
-- RX part/control |
v_rx_add_o : out std_logic_vector(15 downto 0); -- 16 bits full addr ram input |
v_rx_data_o : out std_logic_vector(31 downto 0); -- 32 bits full data ram input |
s_rx_rdy_o : out std_logic; -- add/data ready to be write into RAM |
s_rx_stb_read_data_i : in std_logic; -- strobe signal from RAM ... |
-- TX part/control |
s_tx_proc_rqst_i : in std_logic; -- stream TX process request 1/0 tx enable/disable |
v_tx_add_ram_i : in std_logic_vector(15 downto 0); -- 16 bits full addr ram output |
v_tx_data_ram_i : in std_logic_vector(31 downto 0); -- 32 bits full data ram output |
s_tx_ram_data_rdy_i : in std_logic; -- ram output data ready and stable |
s_tx_stb_ram_data_acq_o : out std_logic -- strobe ram data/address output acquired 1/0 acquired/not acquired |
); |
end entity; |
|
--============================================================================= |
-- architecture declaration |
--============================================================================= |
|
architecture a of uart_16550_wrapper is |
|
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-- Components declaration |
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
component gh_uart_16550 is |
port( |
clk : in std_logic; -- UART clock (toward logic) |
BR_clk : in std_logic; -- Baudrate generator clock TX and RX |
rst : in std_logic; -- Reset |
rst_buffer : in std_logic; -- Reset for FIFO and TX and RX |
CS : in std_logic; -- Chip select -> 1 Cycle long CS strobe = 1 data transaction (w/r) |
WR : in std_logic; -- WRITE when HIGH with CS high | READ when LOW with CS high |
ADD : in std_logic_vector(2 downto 0); -- ADDRESS BUS |
D : in std_logic_vector(7 downto 0); -- Input DATA BUS and CONTROL BUS |
|
sRX : in std_logic; -- Lantronix's OUTPUT |
CTSn : in std_logic := '1'; |
DSRn : in std_logic := '1'; |
RIn : in std_logic := '1'; |
DCDn : in std_logic := '1'; |
|
sTX : out std_logic; -- Lantronix's INPUT |
DTRn : out std_logic; |
RTSn : out std_logic; |
OUT1n : out std_logic; |
OUT2n : out std_logic; |
TXRDYn : out std_logic; -- Tx FIFO not Full |
RXRDYn : out std_logic; -- Rx FIFO Data Ready |
|
IRQ : out std_logic; |
B_CLK : out std_logic; -- 16x Baudrate clock output |
RD : out std_logic_vector(7 downto 0) -- Output DATA BUS |
); |
end component; |
|
component uart_lbus is |
generic ( |
c_bus_width : natural := 8 |
); |
port ( |
lbus_clk : in std_logic; -- local bus clock |
lbus_rst : in std_logic; -- local bus reset |
lbus_rst_buffer : out std_logic; -- Reset for FIFO and TX and RX |
lbus_txrdy_n : in std_logic; -- Tx data ready |
lbus_rxrdy_n : in std_logic; -- Rx data ready |
lbus_cs : out std_logic; -- Chip Select |
lbus_wr : out std_logic; -- Write/Read (1/0) |
lbus_init : out std_logic; -- Initialization process flag |
lbus_add : out std_logic_vector(2 downto 0); -- local bus address |
lbus_data : out std_logic_vector(c_bus_width-1 downto 0); -- local bus data |
s_tx_proc_rqst_i : in std_logic; -- tx process request from RAM |
v_lbus_state : out std_logic_vector(2 downto 0); -- flag indicator of lbus_state |
s_cs_rd_c : out std_logic; -- CS signal from caused by read cycle |
s_wr_rd_c : out std_logic; -- WR signal from caused by read cycle |
s_new_byte_rdy : in std_logic; -- new byte(8bit)ready and stable to be transmitted |
s_data_tx : in std_logic; -- 6 bytes will be trasmitted |
reghnd_rd_rdy : in std_logic; -- 6 byte RX ready but not yet written in RAM (1/0=>data ready/not ready) |
echo_en_i : in std_logic -- echo enable command enable/disable = 1/0 |
); |
end component; |
|
component register_rx_handler |
port( |
reghnd_clk : in std_logic; -- system clock |
reghnd_rst : in std_logic; -- system reset |
reghnd_data_in : in std_logic_vector(7 downto 0); -- 8 bits fragments |
reghnd_data_cs_rd : in std_logic; -- cs strobe of gh16550 during a read process |
reghnd_data_wr_rd : in std_logic; -- wr state of gh16550 during a read process |
reghnd_rd_rdy : out std_logic; -- Read data ready |
reghnd_full_add : out std_logic_vector(15 downto 0); -- 16 bits RAM address |
reghnd_full_data : out std_logic_vector(31 downto 0); -- 32 bits RAM data |
reghnd_full_cs : in std_logic -- strobe data/address acquired (1 acquired - 0 not acquired) |
); |
end component; |
|
component register_tx_handler |
port( |
reghnd_clk : in std_logic; -- system clock |
reghnd_rst : in std_logic; -- system reset |
reghnd_addr_wwo_i : in std_logic; -- control of TX process With or WithOut address W/WO=(1/0) |
reghnd_full_data_ram_i : in std_logic_vector(31 downto 0); -- 32 bits full data |
reghnd_full_add_ram_i : in std_logic_vector(15 downto 0); -- 16 bits full addr |
reghnd_stb_data_ram_rdy_i : in std_logic; -- strobe ram data ready |
reghnd_data_acq_gh16550_i : in std_logic; -- data acquired from gh16550 |
reghnd_wr_enable_i : in std_logic; -- enable the tx process |
reghnd_txrdy_n_gh16550_i : in std_logic; -- gh16550 ready to trasmit |
reghnd_wr_enable_o : out std_logic; -- enable the tx process |
reghnd_output_rdy_o : out std_logic; -- Read data ready |
reghnd_pdata_o : out std_logic_vector(7 downto 0); -- 8 bits parallel |
reghnd_stb_acq_ram_o : out std_logic -- strobe data/address acquired (1 acquired - 0 not acquired) |
); |
end component; |
|
-- |
-- Internal signal declaration |
-- |
|
signal s_rst : std_logic; -- global reset |
signal s_rst_buffer : std_logic; -- soft reset for FIFO and TX and RX uart FSM |
signal s_clk : std_logic; -- uart to parallel interface clock |
signal s_clk_n : std_logic; -- uart to parallel interface clock |
signal s_br_clk : std_logic; -- uart serializer clock |
signal s_open : std_logic_vector(32 downto 0) := (others => '0'); -- unused pins |
|
signal s_cs : std_logic; -- chip select (data strobe) |
signal s_wr : std_logic; -- read/write on data bus |
signal lbus_init : std_logic; -- register initialization |
signal lbus_add : std_logic_vector(2 downto 0); -- local bus arbiter address bus |
signal lbus_data : std_logic_vector(7 downto 0); -- local bus arbiter data bus |
|
signal uart_txrdy_n : std_logic; -- tx FIFO Data Ready |
signal uart_rxrdy_n : std_logic; -- rx FIFO Data Ready |
signal uart_add_bus : std_logic_vector(2 downto 0); -- address bus |
signal uart_data_bus : std_logic_vector(7 downto 0); -- data bus |
signal uart_rd : std_logic_vector(7 downto 0); -- UART Rx output data bus |
signal v_write_bus_latch : std_logic_vector(7 downto 0); -- WRITE data bus latched |
signal v_read_bus_latch : std_logic_vector(7 downto 0); -- READ data bus latched |
|
-------------------------------------------------------------------------------------------------- |
-- v_lcr structure: |
-- |
-- 0-1 : number of bits |
-- 00 -> 5 | 01 -> 6 | 10 -> 7 | 11 -> 8 |
-- 2 : number of stop bits |
-- 0 -> 1bit | 1 -> 2bits |
-- 3 : parity bit |
-- 0 -> no party | 1 -> parity |
-- 4 : parity type |
-- 0 -> odd | 1 -> even |
-- 5 : sticky parity (NOT IMPLEMENTED) |
-- 6 : set break |
-- 0 -> normal operation |
-- 1 -> serial output is forced to logic 0 |
-- (Spacing State, which will cause a Break interrupt in the receiver) |
-- 7 : Divisor Latch (baud rate generator) Access bit |
-- 0 -> set Baud rate divisor |
-- 1 -> access FIFO registers |
-- |
-------------------------------------------------------------------------------------------------- |
|
signal v_lcr : std_logic_vector(7 downto 0); -- Line Control Register |
|
-------------------------------------------------------------------------------------------------- |
-- v_fcr structure: |
-- |
-- 0 : FIFO enable |
-- X -> FIFOs are always enabled |
-- 1 : RECEIVER FIFO reset active HIGH |
-- 2 : TRANSMITTER FIFO reset active HIGH |
-- 3 : DMA mode |
-- 0 -> Mode 0 (Supports single transfer DMA) |
-- 1 -> Mode 1 (Supports multiple transfers) |
-- 4-5 : Reserved bits |
-- 6-7 : Receiver FIFO trigger level |
-- 00 -> 1 | 01 -> 4 | 10 -> 8 | 11 -> 14 Bytes |
-- |
-------------------------------------------------------------------------------------------------- |
|
signal v_fcr : std_logic_vector(7 downto 0); -- FIFO Control Register |
|
-------------------------------------------------------------------------------------------------- |
-- v_lsr structure: |
-- |
-- 0 : Data Ready |
-- 0 -> Receive FIFO is empty |
-- 1 -> at lest one character is in the receive FIFO |
-- 1 : Overrun Error |
-- 0 -> no error |
-- 1 -> Receive FIFO was full, additional character received but was lost |
-- 2 : Parity Error |
-- 0 -> no error |
-- 1 -> top character in FIFO received with parity error |
-- -> Receiver Line Status Interrupt |
-- 3 : Framing Error |
-- 0 -> no error |
-- 1 -> top character in FIFO received without a valid stop bit |
-- -> Receiver Line Status Interrupt |
-- 4 : Break Interrupt |
-- 0 -> No Interrupt |
-- 1 -> break condition (uart_srx -> '0' for a character period) |
-- -> Receiver Line Status Interrupt |
-- 5 : Transmitter Holding Register |
-- 0 -> Transmitter FIFO not Empty |
-- 1 -> Transmitter FIFO Empty if enabled |
-- -> Transmitter Holding Empty Interrupt |
-- 6 : Transmitter Empty |
-- 0 -> not 1 |
-- 1 -> Transmitter FIFO and Transmitter Shift Register Empty. |
-- 7 : Error in receive FIFO |
-- 0 -> not 1 |
-- 1 -> at least one error (parity, framing or break) in receive FIFO. |
-- -> cleared upon reading the register |
-- |
-------------------------------------------------------------------------------------------------- |
|
signal v_lsr : std_logic_vector(7 downto 0); -- Line Status Register |
|
-------------------------------------------------------------------------------------------------- |
-- v_iir structure: |
-- |
-- 0 : Interrupt pending |
-- 0 -> Interrupt pending |
-- 1 -> No Interrupt pending |
-- 3-1 : |
-- 010 -> Receiver Data Available ( Rx FIFO trigger level reached) |
-- |
-------------------------------------------------------------------------------------------------- |
|
signal v_iir : std_logic_vector(7 downto 0); -- Interrupt Identification Register |
|
-------------------------------------------------------------------------------------------------- |
-- Baud Rate Generator: |
-- Baud rate division ratio = (s_br_clk /(baudrate x 16)) |
-- |
-- Baud rate division ratio (16 bits) = c_divisor_msb (8 bits) + c_divisor_lsb (8 bits) |
-- |
-- Set useing: LCR bit 7 -> 1 |
-------------------------------------------------------------------------------------------------- |
|
-- signal c_divisor_lsb : std_logic_vector(7 downto 0); -- Divisor Latch LSB (Baud Rate Generator) |
-- signal c_divisor_msb : std_logic_vector(7 downto 0); -- Divisor Latch MSB (Baud Rate Generator) |
|
signal v_unused_write : std_logic_vector(7 downto 0); -- Unused registers |
signal v_unused_read : std_logic_vector(7 downto 0); -- Unused registers |
|
signal v_lbus_state : std_logic_vector(2 downto 0); |
signal s_reading_proc : std_logic; |
signal s_cs_rd_c : std_logic; |
signal s_wr_rd_c : std_logic; |
signal s_writing_proc : std_logic; |
signal v_data8_ram : std_logic_vector (7 downto 0); |
signal s_data8_ram_rdy : std_logic; |
signal s_wr_enable_o : std_logic; |
signal s_not_ready : std_logic; |
|
--============================================================================= |
-- architecture begin |
--============================================================================= |
|
begin |
|
s_clk <= sys_clk_i; -- 14,xxx MHz main clock single ended buffer and division by one |
-- and 1 Mbit/s with Lantronix |
s_clk_n <= not s_clk; |
s_rst <= sys_rst_i; |
s_br_clk <= s_clk; |
|
s_reading_proc <= v_lbus_state(1); |
s_writing_proc <= v_lbus_state(2); |
|
s_rx_rdy_o <= s_not_ready; |
|
--************************************************************************** |
-- UART read/write bus access |
-- |
--************************************************************************** |
-- read: |
-- write: |
-- r/w: |
|
p_uart_RW_bus : process(s_rst, s_clk) |
begin |
if s_rst = '1' then |
uart_data_bus <= (others => '0'); |
uart_add_bus <= (others => '0'); |
v_unused_write <= (others => '0'); |
v_unused_read <= (others => '0'); |
v_fcr <= (others => '0'); |
v_lcr <= (others => '0'); |
v_lsr <= (others => '0'); |
elsif Rising_edge(s_clk) then |
uart_add_bus <= lbus_add; |
case v_lbus_state is |
when "001" => -- init |
case uart_add_bus (2 downto 0) is |
when O"0" => uart_data_bus <= lbus_data; -- init Divisor latch lsb |
when O"1" => uart_data_bus <= lbus_data; -- init Divisor latch msb |
when O"2" => uart_data_bus <= lbus_data; |
v_fcr <= lbus_data; -- FIFO Control Register |
when O"3" => uart_data_bus <= lbus_data; |
v_lcr <= lbus_data; -- Line Control Register |
when others => null; |
end case; |
when "100" => -- write |
case uart_add_bus (2 downto 0) is |
when O"0" => uart_data_bus <= v_write_bus_latch; -- write TRANSMITTER FIFO |
when O"1" => uart_data_bus <= lbus_data; -- Interrupt Enable Register |
when O"2" => uart_data_bus <= lbus_data; |
v_fcr <= lbus_data; -- FIFO Control Register |
when O"3" => uart_data_bus <= lbus_data; |
v_lcr <= lbus_data; -- Line Control Register |
when O"4" => uart_data_bus <= v_unused_write; -- Modem Control Register |
when O"7" => uart_data_bus <= v_unused_write; -- Scretch Register |
when others => null; |
end case; |
when "010" => -- read |
case uart_add_bus (2 downto 0) is |
when O"0" => uart_data_bus <= v_read_bus_latch; --uart_rd; -- read RECEIVER FIFO |
when O"1" => v_unused_read <= uart_data_bus; -- Interrupt Enable Register |
when O"2" => v_iir <= uart_data_bus; -- Interrupt Identification Register |
when O"3" => v_unused_read <= uart_data_bus; -- Line Control Register |
when O"4" => v_unused_read <= uart_data_bus; -- Modem Control Register |
when O"5" => v_lsr <= uart_data_bus; -- Line Status Register |
when O"6" => v_unused_read <= uart_data_bus; -- Modem Status Register |
when O"7" => v_unused_read <= uart_data_bus; -- Scratch Register |
when others => null; |
end case; |
when others => -- idle |
case uart_add_bus (2 downto 0) is |
when O"0" => uart_data_bus <= (others => '0'); --uart_rd; -- read RECEIVER FIFO |
when O"1" => v_unused_read <= uart_data_bus; -- Interrupt Enable Register |
when O"2" => v_iir <= uart_data_bus; -- Interrupt Identification Register |
when O"3" => v_unused_read <= uart_data_bus; -- Line Control Register |
when O"4" => v_unused_read <= uart_data_bus; -- Modem Control Register |
when O"5" => v_lsr <= uart_data_bus; -- Line Status Register |
when O"6" => v_unused_read <= uart_data_bus; -- Modem Status Register |
when O"7" => v_unused_read <= uart_data_bus; -- Scratch Register |
when others => null; |
end case; |
end case; |
end if; |
end process p_uart_RW_bus; |
|
--************************************************************************** |
-- UART register latch update |
--************************************************************************** |
-- read: |
-- write: |
-- r/w: |
|
p_uart_read_latch : process(s_rst, s_reading_proc) |
begin |
if s_rst = '1' then |
v_read_bus_latch <= (others => '0'); |
elsif rising_edge (s_reading_proc) then |
if s_cs = '0' and s_wr = '0' then |
v_read_bus_latch <= uart_rd; |
end if; |
end if; |
end process p_uart_read_latch; |
|
p_uart_write_latch : process(s_rst, s_data8_ram_rdy) |
begin |
if s_rst = '1' then |
v_write_bus_latch <= (others => '0'); |
elsif rising_edge (s_data8_ram_rdy) then |
if s_cs = '0' and s_wr = '1'then |
v_write_bus_latch <= v_data8_ram; |
end if; |
end if; |
end process p_uart_write_latch; |
|
-- p_uart_read_latch : process(s_rst, s_clk_n) |
-- begin |
-- if s_rst = '1' then |
-- v_read_bus_latch <= (others => '0'); |
-- elsif rising_edge (s_clk_n) then |
-- if s_reading_proc = '1' and s_cs = '0' and s_wr = '0' then |
-- v_read_bus_latch <= uart_rd; |
-- else |
-- v_read_bus_latch <= uart_rd; |
-- end if; |
-- end if; |
-- end process p_uart_read_latch; |
|
-- p_uart_write_latch : process(s_rst, s_clk_n) |
-- begin |
-- if s_rst = '1' then |
-- v_write_bus_latch <= (others => '0'); |
-- elsif rising_edge (s_clk_n) then |
-- if s_data8_ram_rdy = '1' and s_cs = '0' and s_wr = '1' then |
-- v_write_bus_latch <= v_data8_ram; |
-- else |
-- v_write_bus_latch <= (others => '0'); |
-- end if; |
-- end if; |
-- end process p_uart_write_latch; |
|
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-- Components mapping |
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
cmp_uart : gh_uart_16550 |
port map ( |
clk => s_clk, -- uart clock |
BR_clk => s_br_clk, -- Baudrate generator clock TX and RX |
rst => s_rst, -- Reset |
rst_buffer => s_rst_buffer, -- soft fifo release reset after init |
CS => s_cs, -- Chip select -> 1 Cycle long CS strobe = 1 data transaction (w/r) |
WR => s_wr, -- WRITE when HIGH with CS high | READ when LOW with CS high |
ADD => uart_add_bus, -- ADDRESS BUS |
D => uart_data_bus, -- Input DATA BUS and CONTROL BUS |
sRX => lantronix_output_i, -- Lantronix's OUTPUT |
CTSn => '1', -- not used |
DSRn => '1', -- not used |
RIn => '1', -- not used |
DCDn => '1', -- not used |
|
sTX => lantronix_input_o, -- Lantronix's INPUT |
DTRn => open, -- not used |
RTSn => open, -- not used |
OUT1n => open, -- not used |
OUT2n => open, -- not used |
TXRDYn => uart_txrdy_n, -- Tx FIFO not Fully |
RXRDYn => uart_rxrdy_n, -- Rx FIFO Data Ready |
|
IRQ => open, -- not used |
B_CLK => s_br_clk_uart_o, -- br_clk clock probe signal |
RD => uart_rd -- read data |
); |
|
cmp_uart_lbus : uart_lbus |
port map ( |
lbus_clk => s_clk, -- uart clock |
lbus_rst => s_rst, -- system reset |
lbus_rst_buffer => s_rst_buffer, -- soft UART FIFO reset |
lbus_txrdy_n => uart_txrdy_n, -- Tx data ready |
lbus_rxrdy_n => uart_rxrdy_n, -- Rx data ready |
lbus_cs => s_cs, -- Chip Select gh16550 |
lbus_wr => s_wr, -- Write/Read (1/0) gh16550 |
lbus_init => lbus_init, -- Initialization process flag |
lbus_add => lbus_add, -- local bus address |
lbus_data => lbus_data, -- local bus data |
s_tx_proc_rqst_i => s_tx_proc_rqst_i, -- tx process request from RAM |
v_lbus_state => v_lbus_state, -- flag indicator of lbus_state |
s_cs_rd_c => s_cs_rd_c, -- CS signal from caused by read cycle |
s_wr_rd_c => s_wr_rd_c, -- WR signal from caused by read cycle |
s_new_byte_rdy => s_data8_ram_rdy, -- new byte(8bit)ready and stable to be transmitted |
s_data_tx => s_wr_enable_o, -- 6 bytes will be trasmitted |
reghnd_rd_rdy => s_not_ready, -- 6 byte ready but not yet written in RAM (1/0=>data ready/not ready) |
echo_en_i => echo_en_i -- echo enable command enable/disable = 1/0 |
); |
|
cmp_register_rx_handler: register_rx_handler |
port map( |
reghnd_clk => s_clk, -- system clock |
reghnd_rst => s_rst, -- system reset |
reghnd_data_in => v_read_bus_latch, -- 8 bits handler input from gh16550 RD through latch |
reghnd_data_cs_rd => s_cs_rd_c, -- cs strobe of gh16550 during a read process |
reghnd_data_wr_rd => s_wr_rd_c, -- wr state of gh16550 during a read process |
reghnd_rd_rdy => s_not_ready, -- data and address ready and stable at handler output |
reghnd_full_add => v_rx_add_o, -- 16 bits full addr ram input |
reghnd_full_data => v_rx_data_o, -- 32 bits full data ram input |
reghnd_full_cs => s_rx_stb_read_data_i -- strobe data/address acquired (1 acquired - 0 not acquired) |
); |
|
cmp_register_tx_handler: register_tx_handler |
port map( |
reghnd_clk => s_clk, -- system clock |
reghnd_rst => s_rst, -- system reset |
reghnd_addr_wwo_i => tx_addr_wwo_i, -- control of TX process With or WithOut address W/WO=(1/0) |
reghnd_full_data_ram_i => v_tx_data_ram_i, -- 32 bits full data ram output |
reghnd_full_add_ram_i => v_tx_add_ram_i, -- 16 bits full addr ram output |
reghnd_stb_data_ram_rdy_i => s_tx_ram_data_rdy_i, -- strobe ram output data ready and stable |
reghnd_data_acq_gh16550_i => s_cs, -- data acquired from gh16550 |
reghnd_wr_enable_i => s_writing_proc, -- enable the tx process |
reghnd_txrdy_n_gh16550_i => uart_txrdy_n, -- gh16550 ready to trasmit |
reghnd_wr_enable_o => s_wr_enable_o, -- enable the tx process |
reghnd_output_rdy_o => s_data8_ram_rdy, -- output data(8) ready |
reghnd_pdata_o => v_data8_ram, -- 8 bits parallel |
reghnd_stb_acq_ram_o => s_tx_stb_ram_data_acq_o -- strobe data/address acquired (1 acquired - 0 not acquired) |
); |
|
end a; |
|
--============================================================================= |
-- architecture end |
--============================================================================= |
/ab_register_tx_handler.vhd
0,0 → 1,406
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- -- |
-- -- |
------------------------------------------------------------------------------- |
-- |
-- unit name: register_tx_handler |
-- |
-- author: Mauro Predonzani (mauro.predonzani@elettra.trieste.it) |
-- |
-- date: 20/02/2009 $: created |
-- |
-- version: $Rev 1.0 $: |
-- |
-- description: |
-- |
-- the module acquires byte |
-- and decodes the data as follows: |
-- |
-- reghnd_addr_wwo_i= 1 (with) |
-- ----------------------------------------------------- |
-- | ADDRESS | DATA | |
-- ----------------------------------------------------- |
-- | 15-08 | 07-00 | 31-24 | 23-16 | 15-08 | 07-00 | |
-- | full_add_ram_i | reghnd_full_data_ram_i | |
-- ----------------------------------------------------- |
-- BYTE NUM | BYTEO | BYTE1 | BYTE2 | BYTE3 | BYTE4 | BYTE5 | |
-- ----------------------------------------------------- |
-- |
-- reghnd_addr_wwo_i= 0 (without) |
-- --------------------------------- |
-- | DATA | |
-- --------------------------------- |
-- | 31-24 | 23-16 | 15-08 | 07-00 | |
-- | reghnd_full_data_ram_i | |
-- --------------------------------- |
-- BYTE NUM | BYTE0 | BYTE1 | BYTE2 | BYTE3 | |
-- --------------------------------- |
-- |
-- number of register cells: 2^16 |
-- data word lenght: 32 bits |
-- |
-- |
-- dependencies: Lantronix_wrapper |
-- uart_lbus_slave |
-- gh_uart_16550 |
-- |
-- references: <reference one> |
-- <reference two> ... |
-- |
-- modified by: $Author:: $: |
-- |
------------------------------------------------------------------------------- |
-- last changes: 2010-06-09 enable/disable TX address byte -- Mauro Predonzani |
-- <extended description> |
------------------------------------------------------------------------------- |
-- TODO: |
-- |
-- |
-- |
-- |
------------------------------------------------------------------------------- |
|
--============================================================================= |
-- Libraries |
--============================================================================= |
|
library ieee ; |
use ieee.std_logic_1164.all ; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
--============================================================================= |
-- Entity declaration for ada_register_handler |
--============================================================================= |
|
entity register_tx_handler is |
port( |
reghnd_clk : in std_logic; -- system clock |
reghnd_rst : in std_logic; -- system reset |
reghnd_addr_wwo_i : in std_logic; -- control of TX process With or WithOut address W/WO=(1/0) |
reghnd_full_data_ram_i : in std_logic_vector(31 downto 0); -- 32 bits full data |
reghnd_full_add_ram_i : in std_logic_vector(15 downto 0); -- 16 bits full addr |
reghnd_stb_data_ram_rdy_i : in std_logic; -- strobe ram data ready |
reghnd_data_acq_gh16550_i : in std_logic; -- data acquired from gh16550 |
reghnd_wr_enable_i : in std_logic; -- enable the tx process |
reghnd_txrdy_n_gh16550_i : in std_logic; -- gh16550 ready to trasmit |
reghnd_wr_enable_o : out std_logic; -- enable the tx process |
reghnd_output_rdy_o : out std_logic; -- Read data ready |
reghnd_pdata_o : out std_logic_vector(7 downto 0); -- 8 bits parallel |
reghnd_stb_acq_ram_o : out std_logic -- strobe data/address acquired (1 acquired - 0 not acquired) |
); |
end entity; |
|
--============================================================================= |
-- architecture declaration |
--============================================================================= |
|
architecture tx_handler of register_tx_handler is |
|
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-- Components declaration |
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
-- |
-- Internal signal declaration |
-- |
|
signal s_rst : std_logic; -- global reset |
signal s_clk : std_logic; -- uart to parallel interface clock |
signal s_tick : std_logic_vector (1 downto 0); |
signal v_tx_stream : std_logic_vector(47 downto 0); |
-- |
-- State Machine states |
-- |
|
type t_reg_decoder is (IDLE, READ_RAM, BYTE0, BYTE1, BYTE2, BYTE3, BYTE4, BYTE5 ); |
signal s_reg_decoder : t_reg_decoder; |
|
--============================================================================= |
-- architecture begin |
--============================================================================= |
|
begin |
|
s_rst <= reghnd_rst; |
s_clk <= reghnd_clk; |
|
p_tx_handler : process(s_rst, s_clk) |
begin |
if s_rst = '1' then -- reset |
reghnd_wr_enable_o <= '0'; |
reghnd_output_rdy_o <= '0'; |
reghnd_pdata_o <= (others => '0'); |
reghnd_stb_acq_ram_o <= '0'; |
s_tick <= "00"; |
v_tx_stream <= (others => '0'); |
s_reg_decoder <= IDLE; |
elsif Rising_edge(s_clk) then |
case s_reg_decoder is |
when IDLE => -- IDLE state |
reghnd_wr_enable_o <= '0'; |
reghnd_output_rdy_o <= '0'; |
reghnd_pdata_o <= (others => '0'); |
reghnd_stb_acq_ram_o <= '0'; |
s_tick <= "00"; |
if reghnd_txrdy_n_gh16550_i = '0' and reghnd_stb_data_ram_rdy_i = '1' then -- check if BYTE0 is ready |
s_reg_decoder <= READ_RAM; |
else |
s_reg_decoder <= IDLE; |
end if; |
when READ_RAM => |
if s_tick = "00" then -- only first time in this cycle acq the byte |
v_tx_stream (47 downto 32) <= reghnd_full_add_ram_i; |
v_tx_stream (31 downto 0) <= reghnd_full_data_ram_i; |
reghnd_pdata_o <= (others => '0'); |
reghnd_stb_acq_ram_o <= '1'; |
s_tick <= "01"; |
reghnd_wr_enable_o <= '0'; |
elsif reghnd_wr_enable_i = '0' then |
s_reg_decoder <= IDLE; |
reghnd_pdata_o <= (others => '0'); |
s_tick <= "00"; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_wr_enable_o <= '0'; |
elsif reghnd_txrdy_n_gh16550_i = '0' and reghnd_wr_enable_i = '1' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
if reghnd_addr_wwo_i = '1' then |
s_reg_decoder <= BYTE0; |
reghnd_pdata_o <= v_tx_stream (47 downto 40); |
else |
s_reg_decoder <= BYTE2; |
reghnd_pdata_o <= v_tx_stream (31 downto 24); |
end if; |
s_tick <= "00"; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_wr_enable_o <= '1'; -- inizio la trasmissione |
else |
reghnd_pdata_o <= v_tx_stream (47 downto 40); |
s_reg_decoder <= READ_RAM; |
s_tick <= "01"; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_wr_enable_o <= '0'; |
end if; |
when BYTE0 => -- send byte 0 ADDRESS higher |
reghnd_wr_enable_o <= '1'; |
if s_tick = "00" then -- only first time in this cycle acq the byte |
s_reg_decoder <= BYTE0; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (47 downto 40); |
if reghnd_data_acq_gh16550_i = '1' then |
s_tick <= "01"; |
else |
s_tick <= "00"; |
end if; |
elsif s_tick = "01" then |
s_tick <= "11"; |
s_reg_decoder <= BYTE0; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (47 downto 40); |
elsif s_tick = "11" then |
s_tick <= "10"; |
s_reg_decoder <= BYTE0; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (47 downto 40); |
elsif reghnd_txrdy_n_gh16550_i = '0' and reghnd_wr_enable_i = '1' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
s_reg_decoder <= BYTE1; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (39 downto 32); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "00"; |
else |
s_reg_decoder <= BYTE0; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (39 downto 32); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "10"; |
end if; |
when BYTE1 => -- send byte 1 ADDRESS lower |
reghnd_wr_enable_o <= '1'; |
if s_tick = "00" then -- only first time in this cycle acq the byte |
s_reg_decoder <= BYTE1; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (39 downto 32); |
if reghnd_data_acq_gh16550_i = '1' then |
s_tick <= "01"; |
else |
s_tick <= "00"; |
end if; |
elsif s_tick = "01" then |
s_tick <= "11"; |
s_reg_decoder <= BYTE1; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (39 downto 32); |
elsif s_tick = "11" then |
s_tick <= "10"; |
s_reg_decoder <= BYTE1; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (39 downto 32); |
elsif reghnd_txrdy_n_gh16550_i = '0' and reghnd_wr_enable_i = '1' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
s_reg_decoder <= BYTE2; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (31 downto 24); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "00"; |
else |
s_reg_decoder <= BYTE1; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (31 downto 24); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "10"; |
end if; |
when BYTE2 => -- send byte 2 DATA1 |
reghnd_wr_enable_o <= '1'; |
if s_tick = "00" then -- only first time in this cycle acq the byte |
s_reg_decoder <= BYTE2; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (31 downto 24); |
if reghnd_data_acq_gh16550_i = '1' then |
s_tick <= "01"; |
else |
s_tick <= "00"; |
end if; |
elsif s_tick = "01" then |
s_tick <= "11"; |
s_reg_decoder <= BYTE2; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (31 downto 24); |
elsif s_tick = "11" then |
s_tick <= "10"; |
s_reg_decoder <= BYTE2; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (31 downto 24); |
elsif reghnd_txrdy_n_gh16550_i = '0' and reghnd_wr_enable_i = '1' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
s_reg_decoder <= BYTE3; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (23 downto 16); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "00"; |
else |
s_reg_decoder <= BYTE2; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (23 downto 16); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "10"; |
end if; |
when BYTE3 => -- send byte 3 DATA2 |
reghnd_wr_enable_o <= '1'; |
if s_tick = "00" then -- only first time in this cycle acq the byte |
s_reg_decoder <= BYTE3; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (23 downto 16); |
if reghnd_data_acq_gh16550_i = '1' then |
s_tick <= "01"; |
else |
s_tick <= "00"; |
end if; |
elsif s_tick = "01" then |
s_tick <= "11"; |
s_reg_decoder <= BYTE3; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (23 downto 16); |
elsif s_tick = "11" then |
s_tick <= "10"; |
s_reg_decoder <= BYTE3; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (23 downto 16); |
elsif reghnd_txrdy_n_gh16550_i = '0' and reghnd_wr_enable_i = '1' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
s_reg_decoder <= BYTE4; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (15 downto 8); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "00"; |
else |
s_reg_decoder <= BYTE3; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (15 downto 8); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "10"; |
end if; |
when BYTE4 => -- send byte 4 DATA3 |
reghnd_wr_enable_o <= '1'; |
if s_tick = "00" then -- only first time in this cycle acq the byte |
s_reg_decoder <= BYTE4; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (15 downto 8); |
if reghnd_data_acq_gh16550_i = '1' then |
s_tick <= "01"; |
else |
s_tick <= "00"; |
end if; |
elsif s_tick = "01" then |
s_tick <= "11"; |
s_reg_decoder <= BYTE4; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (15 downto 8); |
elsif s_tick = "11" then |
s_tick <= "10"; |
s_reg_decoder <= BYTE4; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (15 downto 8); |
elsif reghnd_txrdy_n_gh16550_i = '0' and reghnd_wr_enable_i = '1' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
s_reg_decoder <= BYTE5; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (7 downto 0); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "00"; |
else |
s_reg_decoder <= BYTE4; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (7 downto 0); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "10"; |
end if; |
when BYTE5 => -- send byte 5 DATA4 |
reghnd_wr_enable_o <= '1'; |
if s_tick = "00" then -- only first time in this cycle acq the byte |
s_reg_decoder <= BYTE5; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (7 downto 0); |
if reghnd_data_acq_gh16550_i = '1' then |
s_tick <= "01"; |
else |
s_tick <= "00"; |
end if; |
elsif s_tick = "01" then |
s_tick <= "11"; |
s_reg_decoder <= BYTE5; |
reghnd_output_rdy_o <= '1'; |
reghnd_pdata_o <= v_tx_stream (7 downto 0); |
elsif s_tick = "11" then |
s_tick <= "10"; |
s_reg_decoder <= BYTE5; |
reghnd_output_rdy_o <= '0'; |
reghnd_pdata_o <= v_tx_stream (7 downto 0); |
elsif reghnd_txrdy_n_gh16550_i = '0' and reghnd_wr_enable_i = '1' and reghnd_stb_data_ram_rdy_i = '1' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
s_reg_decoder <= READ_RAM; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= (others => '0'); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "00"; |
elsif reghnd_txrdy_n_gh16550_i = '0' then -- if uart is lbus and gh16550 is ready then tx BYTE0 |
s_reg_decoder <= IDLE; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= (others => '0'); |
reghnd_output_rdy_o <= '0'; |
s_tick <= "00"; |
else |
s_reg_decoder <= BYTE5; |
reghnd_stb_acq_ram_o <= '0'; |
reghnd_pdata_o <= (others => '0'); |
s_tick <= "10"; |
end if; |
when others => |
s_reg_decoder <= IDLE; |
end case; |
end if; |
end process p_tx_handler; |
|
|
end tx_handler; |
|
--============================================================================= |
-- architecture end |
--============================================================================= |