OpenCores
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
--=============================================================================

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.