Commit 833a17ac authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

lpc_uart: moved to bel_cores

parent 5b5bce76
files = [
"lpc_peripheral.vhd",
"lpc_uart.vhd",
"lpc_uart_pkg.vhd",
"postcode.vhd",
"serirq_defines.v",
"serirq_slave.v"
]
This diff is collapsed.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity lpc_uart is
port (
lpc_clk: in std_logic;
lpc_serirq: inout std_logic;
lpc_ad: inout std_logic_vector(3 downto 0);
lpc_frame_n: in std_logic;
lpc_reset_n: in std_logic;
serial_rxd: in std_logic;
serial_txd: out std_logic;
serial_dtr: out std_logic;
serial_dcd: in std_logic;
serial_dsr: in std_logic;
serial_ri: in std_logic;
serial_cts: in std_logic;
serial_rts: out std_logic;
seven_seg_L: out std_logic_vector(7 downto 0); -- SSeg Data output
seven_seg_H: out std_logic_vector(7 downto 0) -- SSeg Data output
);
end lpc_uart;
architecture lpc_uart_arch of lpc_uart is
component lpc_decoder is
Port (
lclk: in std_logic; -- LPC: 33MHz clock (rising edge)
lframe_n: in std_logic; -- LPC: frame, active low
lreset_n: in std_logic; -- LPC: reset, active low
lad: in std_logic_vector(3 downto 0); -- LPC: multiplexed bus
paddr: out std_logic_vector(15 downto 0); -- port addr
pdata_in: out std_logic_vector(7 downto 0); -- data to the slave
pdata_out: in std_logic_vector(7 downto 0); -- data from the slave
paddr_valid: out std_logic;
pdata_valid: out std_logic
);
end component;
component lpc_peripheral is
port (
clk_i: in std_logic;
nrst_i: in std_logic;
lframe_i: in std_logic; -- LPC Frame input (active high)
lad_oe: out std_logic; -- LPC AD Output Enable
lad_i: in std_logic_vector(3 downto 0); -- LPC AD Input Bus
lad_o: out std_logic_vector(3 downto 0); -- LPC AD Output Bus
dma_chan_o: out std_logic_vector(2 downto 0); -- DMA Channel
dma_tc_o: out std_logic; -- DMA Terminal Count
wbm_err_i: in std_logic;
io_bus_dat_o: out std_logic_vector(7 downto 0);
io_bus_dat_i: in std_logic_vector(7 downto 0);
io_bus_addr: out std_logic_vector(15 downto 0);
io_bus_we: out std_logic;
io_ack: in std_logic;
io_data_valid: out std_logic
);
end component;
component postcode is
port (
lclk: in std_logic;
paddr: in std_logic_vector(15 downto 0);
pdata: in std_logic_vector(7 downto 0);
addr_hit: out std_logic;
data_valid: in std_logic;
seven_seg_L: out std_logic_vector(7 downto 0); -- SSeg Data output
seven_seg_H: out std_logic_vector(7 downto 0) -- SSeg Data output
);
end component;
component uart_16750 is
port (
CLK : in std_logic; -- Clock 24Mhz
RST : in std_logic; -- Reset
BAUDCE : in std_logic; -- Baudrate generator clock enable
CS : in std_logic; -- Chip select
WR : in std_logic; -- Write to UART
RD : in std_logic; -- Read from UART
A : in std_logic_vector(2 downto 0); -- Register select
DIN : in std_logic_vector(7 downto 0); -- Data bus input
DOUT : out std_logic_vector(7 downto 0); -- Data bus output
DDIS : out std_logic; -- Driver disable
INT : out std_logic; -- Interrupt output
OUT1N : out std_logic; -- Output 1
OUT2N : out std_logic; -- Output 2
RCLK : in std_logic; -- Receiver clock (16x baudrate)
BAUDOUTN : out std_logic; -- Baudrate generator output (16x baudrate)
RTSN : out std_logic; -- RTS output
DTRN : out std_logic; -- DTR output
CTSN : in std_logic; -- CTS input
DSRN : in std_logic; -- DSR input
DCDN : in std_logic; -- DCD input
RIN : in std_logic; -- RI input
SIN : in std_logic; -- Receiver input
SOUT : out std_logic -- Transmitter output
);
end component;
component uart_pll IS
PORT
(
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC;
c1 : out std_logic
);
END component;
component serirq_slave is
port (
clk_i : in std_logic;
nrst_i : in std_logic;
irq_i : in std_logic_vector(31 downto 0);
serirq_o : out std_logic;
serirq_i : in std_logic;
serirq_oe : out std_logic
);
end component;
constant uart_base_addr: unsigned(15 downto 0) := x"03F8";
signal io_addr: std_logic_vector(15 downto 0);
signal io_to_slave: std_logic_vector(7 downto 0);
signal io_from_slave: std_logic_vector(7 downto 0);
signal s_paddr_valid: std_logic;
signal s_pdata_valid: std_logic;
signal clk_24: std_logic;
signal s_baudout: std_logic;
signal s_uart_addr: std_logic_vector(2 downto 0);
signal s_uart_cs: std_logic;
signal s_addr_hit: std_logic;
signal s_rd_en: std_logic;
signal s_wr_en: std_logic;
signal io_bus_we: std_logic;
signal s_lad_i: std_logic_vector(3 downto 0);
signal s_lad_o: std_logic_vector(3 downto 0);
signal lad_oe: std_logic;
signal io_data_valid: std_logic;
signal rst: std_logic;
signal serirq_i: std_logic;
signal serirq_o: std_logic;
signal serirq_oe: std_logic;
signal irq_vector: std_logic_vector(31 downto 0);
signal uart_int: std_logic;
begin
rst <= not lpc_reset_n;
s_wr_en <= io_bus_we and io_data_valid;
s_rd_en <= not io_bus_we and io_data_valid;
irq_vector <= x"FFFFFF" & "111" & not uart_int & "1111"; -- IRQ4 is IRQ frame 4 on CA945
decoder: lpc_peripheral port map (
clk_i => lpc_clk,
lframe_i => lpc_frame_n,
nrst_i => lpc_reset_n,
lad_oe => lad_oe,
lad_i => s_lad_i,
lad_o => s_lad_o,
dma_chan_o => open,
dma_tc_o => open,
wbm_err_i => '0',
io_bus_dat_o => io_to_slave,
io_bus_dat_i => io_from_slave,
io_bus_addr => io_addr,
io_bus_we => io_bus_we,
io_ack => '1',
io_data_valid => io_data_valid
);
pcode: postcode port map (
lclk => lpc_clk,
data_valid => io_data_valid,
paddr => io_addr,
pdata => io_to_slave,
addr_hit => s_addr_hit,
seven_seg_L => seven_seg_L,
seven_seg_H => seven_seg_H
);
uart: uart_16750 port map (
clk => lpc_clk,
rst => rst,
baudce => '1',
cs => s_uart_cs,
wr => s_wr_en,
rd => s_rd_en,
a => s_uart_addr,
din => io_to_slave,
dout => io_from_slave,
ddis => open,
int => uart_int,
out1n => open,
out2n => open,
rclk => s_baudout,
baudoutn => s_baudout,
rtsn => serial_rts,
dtrn => serial_dtr,
ctsn => serial_cts,
dsrn => serial_dsr,
dcdn => serial_dcd,
rin => serial_ri,
sin => serial_rxd,
sout => serial_txd
);
serirq: serirq_slave port map (
clk_i => lpc_clk,
nrst_i => lpc_reset_n,
irq_i => irq_vector,
serirq_o => serirq_o,
serirq_i => serirq_i,
serirq_oe => serirq_oe
);
tri_lad: process (lad_oe)
begin
if lad_oe = '1' then
lpc_ad <= s_lad_o;
else
lpc_ad <= (others => 'Z');
end if;
end process;
s_lad_i <= lpc_ad;
tri_serirq: process (serirq_oe)
begin
if serirq_oe = '1' then
lpc_serirq <= serirq_o;
else
lpc_serirq <= 'Z';
end if;
end process;
serirq_i <= lpc_serirq;
uart_addr_deco: process (lpc_clk, io_addr)
begin
if rising_edge(lpc_clk) then
case unsigned(io_addr) is
when (uart_base_addr + 0) => s_uart_addr <= "000";
s_uart_cs <= '1';
when (uart_base_addr + 1) => s_uart_addr <= "001";
s_uart_cs <= '1';
when (uart_base_addr + 2) => s_uart_addr <= "010";
s_uart_cs <= '1';
when (uart_base_addr + 3) => s_uart_addr <= "011";
s_uart_cs <= '1';
when (uart_base_addr + 4) => s_uart_addr <= "100";
s_uart_cs <= '1';
when (uart_base_addr + 5) => s_uart_addr <= "101";
s_uart_cs <= '1';
when (uart_base_addr + 6) => s_uart_addr <= "110";
s_uart_cs <= '1';
when (uart_base_addr + 7) => s_uart_addr <= "111";
s_uart_cs <= '1';
when others => s_uart_addr <= "000";
s_uart_cs <= '0';
end case;
end if;
end process;
end architecture;
\ No newline at end of file
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
package lpc_uart_pkg is
component lpc_uart is
port (
lpc_clk: in std_logic;
lpc_serirq: inout std_logic;
lpc_ad: inout std_logic_vector(3 downto 0);
lpc_frame_n: in std_logic;
lpc_reset_n: in std_logic;
serial_rxd: in std_logic;
serial_txd: out std_logic;
serial_dtr: out std_logic;
serial_dcd: in std_logic;
serial_dsr: in std_logic;
serial_ri: in std_logic;
serial_cts: in std_logic;
serial_rts: out std_logic;
seven_seg_L: out std_logic_vector(7 downto 0); -- SSeg Data output
seven_seg_H: out std_logic_vector(7 downto 0) -- SSeg Data output
);
end component;
end lpc_uart_pkg;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity postcode is
port (
lclk: in std_logic;
pdata_valid: in std_logic;
paddr_valid: in std_logic;
paddr: in std_logic_vector(15 downto 0);
pdata: in std_logic_vector(7 downto 0);
addr_hit: out std_logic;
data_valid: in std_logic;
seven_seg_L: out std_logic_vector(7 downto 0); -- SSeg Data output
seven_seg_H: out std_logic_vector(7 downto 0) -- SSeg Data output
);
end entity;
architecture postcode_arch of postcode is
signal postcode_data: std_logic_vector(7 downto 0);
constant postcode_addr: std_logic_vector(15 downto 0) := x"0080";
begin
postcode_reg: process(lclk)
begin
if rising_edge(lclk) then
if (paddr = postcode_addr and data_valid = '1') then
addr_hit <= '1';
postcode_data <= pdata;
else
addr_hit <= '0';
end if;
end if;
end process;
P_sseg_decode: process(lclk) -- decode section for 7 seg displays
begin
if rising_edge(lclk) then
case postcode_data(7 downto 4) is -- Most sig digit for display
when "0000" => seven_seg_H <= "00000011"; -- Hex 03 displays a 0
when "0001" => seven_seg_H <= "10011111"; -- Hex 9f displays a 1
when "0010" => seven_seg_H <= "00100101"; -- Hex 25 displays a 2
when "0011" => seven_seg_H <= "00001101"; -- Hex 0d displays a 3
when "0100" => seven_seg_H <= "10011001"; -- Hex 99 displays a 4
when "0101" => seven_seg_H <= "01001001"; -- Hex 49 displays a 5
when "0110" => seven_seg_H <= "01000001"; -- Hex 41 displays a 6
when "0111" => seven_seg_H <= "00011111"; -- Hex 1f displays a 7
when "1000" => seven_seg_H <= "00000001"; -- Hex 01 displays a 8
when "1001" => seven_seg_H <= "00001001"; -- Hex 09 displays a 9
when "1010" => seven_seg_H <= "00010001"; -- Hex 11 displays a A
when "1011" => seven_seg_H <= "11000001"; -- Hex c1 displays a b
when "1100" => seven_seg_H <= "01100011"; -- Hex 63 displays a C
when "1101" => seven_seg_H <= "10000101"; -- Hex 85 displays a d
when "1110" => seven_seg_H <= "01100001"; -- Hex 61 displays a E
when "1111" => seven_seg_H <= "01110001"; -- Hex 71 displays a F
when others => seven_seg_H <= "00000001"; -- Hex 01 displays a 8
end case;
case postcode_data(3 downto 0) is -- Least sig digit for display
when "0000" => seven_seg_L <= "00000011"; -- Hex 03 displays a 0
when "0001" => seven_seg_L <= "10011111"; -- Hex 9f displays a 1
when "0010" => seven_seg_L <= "00100101"; -- Hex 25 displays a 2
when "0011" => seven_seg_L <= "00001101"; -- Hex 0d displays a 3
when "0100" => seven_seg_L <= "10011001"; -- Hex 99 displays a 4
when "0101" => seven_seg_L <= "01001001"; -- Hex 49 displays a 5
when "0110" => seven_seg_L <= "01000001"; -- Hex 41 displays a 6
when "0111" => seven_seg_L <= "00011111"; -- Hex 1f displays a 7
when "1000" => seven_seg_L <= "00000001"; -- Hex 01 displays a 8
when "1001" => seven_seg_L <= "00001001"; -- Hex 09 displays a 9
when "1010" => seven_seg_L <= "00010001"; -- Hex 11 displays a A
when "1011" => seven_seg_L <= "11000001"; -- Hex c1 displays a b
when "1100" => seven_seg_L <= "01100011"; -- Hex 63 displays a C
when "1101" => seven_seg_L <= "10000101"; -- Hex 85 displays a d
when "1110" => seven_seg_L <= "01100001"; -- Hex 61 displays a E
when "1111" => seven_seg_L <= "01110001"; -- Hex 71 displays a F
when others => seven_seg_L <= "00000001"; -- Hex 01 displays a 8
end case;
end if;
end process;
end architecture;
\ No newline at end of file
//////////////////////////////////////////////////////////////////////
//// ////
//// $Id: serirq_defines.v,v 1.2 2008-12-27 19:46:18 hharte Exp $
//// wb_lpc_defines.v ////
//// ////
//// This file is part of the Wishbone LPC Bridge project ////
//// http://www.opencores.org/projects/wb_lpc/ ////
//// ////
//// Author: ////
//// - Howard M. Harte (hharte@opencores.org) ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2008 Howard M. Harte ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
// Wishbone SERIRQ Host/Slave Interface Definitions
`define SERIRQ_ST_IDLE 13'h000 // SERIRQ Idle state
`define SERIRQ_ST_START 13'h001 // SERIRQ Start state
`define SERIRQ_ST_START_R 13'h002 // SERIRQ Start state
`define SERIRQ_ST_START_T 13'h004 // SERIRQ Start state
`define SERIRQ_ST_IRQ 13'h008 // SERIRQ IRQ Frame State
`define SERIRQ_ST_IRQ_R 13'h010 // SERIRQ IRQ Frame State
`define SERIRQ_ST_IRQ_T 13'h020 // SERIRQ IRQ Frame State
`define SERIRQ_ST_STOP 13'h040 // SERIRQ Stop State
`define SERIRQ_ST_STOP_R 13'h080 // SERIRQ Stop State
`define SERIRQ_ST_STOP_T 13'h100 // SERIRQ Stop State
`define SERIRQ_ST_WAIT_STOP 13'h200
`define SERIRQ_MODE_CONTINUOUS 1'b1 // Serirq "Continuous Mode"
`define SERIRQ_MODE_QUIET 1'b0 // Serirq "Quiet Mode"
\ No newline at end of file
//////////////////////////////////////////////////////////////////////
//// ////
//// $Id: serirq_slave.v,v 1.2 2008-12-27 19:46:18 hharte Exp $ ////
//// serirq_slave.v - Wishbone Slave to SERIRQ Host Bridge ////
//// ////
//// This file is part of the Wishbone LPC Bridge project ////
//// http://www.opencores.org/projects/lpc/ ////
//// ////
//// Author: ////
//// - Howard M. Harte (hharte@opencores.org) ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2008 Howard M. Harte ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
`timescale 1 ns / 1 ns
`include "serirq_defines.v"
module serirq_slave(clk_i, nrst_i,
irq_i,
serirq_o, serirq_i, serirq_oe
);
// Wishbone Slave Interface
input clk_i;
input nrst_i; // Active low reset.
// SERIRQ Master Interface
output reg serirq_o; // SERIRQ output
input serirq_i; // SERIRQ Input
output reg serirq_oe; // SERIRQ Output Enable
input [31:0] irq_i; // IRQ Input Bus
reg [31:0] current_irq;
reg [12:0] state; // Current state
reg [4:0] irq_cnt; // IRQ Frame counter
reg found_stop;
reg found_start;
reg serirq_mode;
wire irq_changed = (serirq_mode & (current_irq != irq_i));
always @(posedge clk_i or negedge nrst_i)
if(~nrst_i)
begin
state <= `SERIRQ_ST_IDLE;
serirq_oe <= 1'b0;
serirq_o <= 4'b1;
irq_cnt <= 5'h00;
current_irq <= irq_i;
end
else begin
case(state)
`SERIRQ_ST_IDLE:
begin
serirq_oe <= 1'b0;
irq_cnt <= 5'h00;
serirq_o <= 1'b1;
if(found_start == 1'b1) // Wait for Start cycle
begin
current_irq <= irq_i;
if(irq_i[irq_cnt] == 1'b0) begin
serirq_oe <= 1'b1;
serirq_o <= 1'b0;
end
state <= `SERIRQ_ST_IRQ_R;
end
else if(irq_changed) begin
current_irq <= irq_i;
serirq_o <= 1'b0;
serirq_oe <= 1'b1;
state <= `SERIRQ_ST_IDLE;
end else
state <= `SERIRQ_ST_IDLE;
end
`SERIRQ_ST_IRQ:
begin
if(irq_i[irq_cnt] == 1'b0) begin
serirq_oe <= 1'b1;
serirq_o <= 1'b0;
end
if(found_stop == 1'b0)
state <= `SERIRQ_ST_IRQ_R;
else
state <= `SERIRQ_ST_IDLE;
end
`SERIRQ_ST_IRQ_R:
begin
serirq_o <= 1'b1;
if(found_stop == 1'b0)
state <= `SERIRQ_ST_IRQ_T;
else
state <= `SERIRQ_ST_IDLE;
end
`SERIRQ_ST_IRQ_T:
begin
serirq_oe <= 1'b0;
if(irq_cnt == 5'h1f)
begin
state <= `SERIRQ_ST_WAIT_STOP;
end
else begin
irq_cnt <= irq_cnt + 1;
if(found_stop == 1'b0)
state <= `SERIRQ_ST_IRQ;
else
state <= `SERIRQ_ST_IDLE;
end
end
`SERIRQ_ST_WAIT_STOP:
begin
if(found_stop == 1'b0)
state <= `SERIRQ_ST_WAIT_STOP;
else
state <= `SERIRQ_ST_IDLE;
end
endcase
end
reg [3:0] stop_clk_cnt;
// Look for STOP cycles
always @(posedge clk_i or negedge nrst_i)
if(~nrst_i)
begin
found_stop <= 1'b0;
found_start <= 1'b0;
serirq_mode <= `SERIRQ_MODE_CONTINUOUS;
stop_clk_cnt <= 4'h0;
end
else begin
if(serirq_i == 1'b0) begin
stop_clk_cnt <= stop_clk_cnt + 1;
end
else begin
case (stop_clk_cnt)
4'h2:
begin
found_stop <= 1'b1;
found_start <= 1'b0;
serirq_mode <= `SERIRQ_MODE_QUIET;
end
4'h3:
begin
found_stop <= 1'b1;
found_start <= 1'b0;
serirq_mode <= `SERIRQ_MODE_CONTINUOUS;
end
4'h4:
begin
found_stop <= 1'b0;
found_start <= 1'b1;
end
4'h6:
begin
found_stop <= 1'b0;
found_start <= 1'b1;
end
4'h8:
begin
found_stop <= 1'b0;
found_start <= 1'b1;
end
default:
begin
found_stop <= 1'b0;
found_start <= 1'b0;
end
endcase
stop_clk_cnt <= 4'h0;
end
end
endmodule
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment