mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2025-01-09 23:30:16 +02:00
ea03c86992
Change Y3 footprint Change D10 footprint Remove J18, Using J17 circuit for switch between USB and DC plug power supply, this remove the possibility that the USB host will be connected to DC wall adapter. Change L13 footprint
244 lines
9.3 KiB
VHDL
244 lines
9.3 KiB
VHDL
---------------------------------------------------------------------
|
|
-- TITLE: Plasma (CPU core with memory)
|
|
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
|
|
-- DATE CREATED: 6/4/02
|
|
-- FILENAME: plasma.vhd
|
|
-- PROJECT: Plasma CPU core
|
|
-- COPYRIGHT: Software placed into the public domain by the author.
|
|
-- Software 'as is' without warranty. Author liable for nothing.
|
|
-- DESCRIPTION:
|
|
-- This entity combines the CPU core with memory and a UART.
|
|
--
|
|
-- Memory Map:
|
|
-- 0x00000000 - 0x0000ffff Internal RAM (8KB)
|
|
-- 0x10000000 - 0x100fffff External RAM (1MB)
|
|
-- Access all Misc registers with 32-bit accesses
|
|
-- 0x20000000 Uart Write (will pause CPU if busy)
|
|
-- 0x20000000 Uart Read
|
|
-- 0x20000010 IRQ Mask
|
|
-- 0x20000020 IRQ Status
|
|
-- 0x20000030 Peripheric 1
|
|
-- 0x20000040 Peripheric 2
|
|
-- 0x20000050 Peripheric 3
|
|
-- 0x20000060 Peripheric 4
|
|
-- IRQ bits:
|
|
-- 1 ^UartWriteBusy
|
|
-- 0 UartDataAvailable
|
|
---------------------------------------------------------------------
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use work.mlite_pack.all;
|
|
|
|
entity plasma is
|
|
generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM";
|
|
log_file : string := "UNUSED");
|
|
port(clk_in : in std_logic;
|
|
rst_in : in std_logic;
|
|
uart_write : out std_logic;
|
|
uart_read : in std_logic;
|
|
addr : in std_logic_vector(12 downto 0);
|
|
sram_data : in std_logic_vector(7 downto 0);
|
|
nwe : in std_logic;
|
|
noe : in std_logic;
|
|
ncs : in std_logic;
|
|
irq_pin : out std_logic;
|
|
led : out std_logic
|
|
);
|
|
end; --entity plasma
|
|
|
|
architecture logic of plasma is
|
|
signal reset : std_logic;
|
|
signal clk : std_logic;
|
|
signal address_next : std_logic_vector(31 downto 2);
|
|
signal byte_we_next : std_logic_vector(3 downto 0);
|
|
signal cpu_address : std_logic_vector(31 downto 0);
|
|
signal cpu_byte_we : std_logic_vector(3 downto 0);
|
|
signal cpu_data_w : std_logic_vector(31 downto 0);
|
|
signal cpu_data_r : std_logic_vector(31 downto 0);
|
|
signal cpu_pause : std_logic;
|
|
|
|
signal bus_dec : std_logic_vector(6 downto 0);
|
|
|
|
signal data_read_uart : std_logic_vector(7 downto 0);
|
|
signal data_read_pic : std_logic_vector(7 downto 0);
|
|
signal write_enable : std_logic;
|
|
signal mem_busy : std_logic;
|
|
|
|
signal cs_pher : std_logic;
|
|
signal cs_uart : std_logic;
|
|
signal cs_pic : std_logic;
|
|
signal cs_p1 : std_logic;
|
|
signal cs_p2 : std_logic;
|
|
signal cs_p3 : std_logic;
|
|
signal cs_p4 : std_logic;
|
|
|
|
signal uart_write_busy : std_logic;
|
|
signal uart_data_avail : std_logic;
|
|
signal irq_mask_reg : std_logic_vector(7 downto 0);
|
|
signal irq_status : std_logic_vector(7 downto 0);
|
|
signal irq : std_logic;
|
|
|
|
signal cs_ram : std_logic;
|
|
signal ram_byte_we : std_logic_vector(3 downto 0);
|
|
signal ram_address : std_logic_vector(31 downto 2);
|
|
signal ram_data_w : std_logic_vector(31 downto 0);
|
|
signal ram_data_r : std_logic_vector(31 downto 0);
|
|
|
|
|
|
begin
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-- CLOCK DIVIDER
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
led <= not(rst_in);
|
|
reset <= not(rst_in);
|
|
irq_pin <= not(rst_in);
|
|
|
|
clk_div: process(reset, clk, clk_in)
|
|
begin
|
|
if reset = '1' then
|
|
clk <= '0';
|
|
elsif rising_edge(clk_in) then
|
|
clk <= not clk;
|
|
end if;
|
|
end process;
|
|
|
|
write_enable <= '1' when cpu_byte_we /= "0000" else '0';
|
|
cpu_pause <= (uart_write_busy and cs_uart and write_enable);
|
|
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-- PROCESSOR
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
u1_cpu: mlite_cpu
|
|
generic map (memory_type => memory_type)
|
|
PORT MAP (
|
|
clk => clk,
|
|
reset_in => reset,
|
|
intr_in => irq,
|
|
address_next => address_next, --before rising_edge(clk)
|
|
byte_we_next => byte_we_next,
|
|
address => cpu_address(31 downto 2), --after rising_edge(clk)
|
|
byte_we => cpu_byte_we,
|
|
data_w => cpu_data_w,
|
|
data_r => cpu_data_r,
|
|
mem_pause => cpu_pause);
|
|
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-- ADDRESS DECODER
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
cpu_address(1 downto 0) <= "00";
|
|
|
|
addr_decoder: process (cpu_address)
|
|
variable addr_dec : std_logic_vector(6 downto 0);
|
|
begin
|
|
addr_dec := cpu_address(30 downto 28) & cpu_address(7 downto 4);
|
|
case addr_dec is
|
|
when "0100000" => cs_uart <= '1'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0';
|
|
when "0100001" => cs_uart <= '0'; cs_pic <= '1'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0';
|
|
when "0100010" => cs_uart <= '0'; cs_pic <= '1'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0';
|
|
when "0100011" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '1'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0';
|
|
when "0100100" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '1'; cs_p3 <= '0'; cs_p4 <= '0';
|
|
when "0100101" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '1'; cs_p4 <= '0';
|
|
when "0100110" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '1';
|
|
when others => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0';
|
|
end case;
|
|
end process;
|
|
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-- BUS MULTIPLEXOR
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
bus_mux: process (cpu_address, ram_data_r, data_read_uart, data_read_pic)
|
|
variable bus_dec : std_logic_vector(4 downto 0);
|
|
begin
|
|
bus_dec := cpu_address(29) & cpu_address(7 downto 4);
|
|
case bus_dec is
|
|
when "00000" | "00001" | "00010" | "00011" | "00100" | "00101" | "00110" | "00111" |
|
|
"01000" | "01001" | "01010" | "01011" | "01100" | "01101" | "01110" | "01111"
|
|
=> cpu_data_r <= ram_data_r;
|
|
when "10000" => cpu_data_r <= ZERO(31 downto 8) & data_read_uart;
|
|
when "10001" => cpu_data_r <= ZERO(31 downto 8) & data_read_pic;
|
|
when "10010" => cpu_data_r <= ZERO(31 downto 8) & data_read_pic;
|
|
when "10011" => cpu_data_r <= ZERO;
|
|
when "10100" => cpu_data_r <= ZERO;
|
|
when "10101" => cpu_data_r <= ZERO;
|
|
when "10110" => cpu_data_r <= ZERO;
|
|
when others => cpu_data_r <= ZERO;
|
|
end case;
|
|
-- end if;
|
|
end process;
|
|
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-- PIC
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
pic_proc: process(clk, reset, cpu_address, cs_pic, cpu_pause, cpu_byte_we, irq_mask_reg, irq_status, cpu_data_w,
|
|
uart_write_busy, uart_data_avail)
|
|
begin
|
|
|
|
irq_status <= ZERO(5 downto 0) & not uart_write_busy & uart_data_avail;
|
|
|
|
if cs_pic = '1' and cpu_byte_we = "0000" then
|
|
case cpu_address(5 downto 4) is
|
|
when "01" => data_read_pic <= irq_mask_reg;
|
|
when "10" => data_read_pic <= irq_status;
|
|
when others => data_read_pic <= ZERO(7 downto 0);
|
|
end case;
|
|
end if;
|
|
|
|
if reset = '1' then
|
|
irq_mask_reg <= ZERO(7 downto 0);
|
|
elsif rising_edge(clk) then
|
|
if cpu_pause = '0' then
|
|
if cs_pic = '1' and cpu_byte_we = "1111" then
|
|
if cpu_address(6 downto 4) = "001" then
|
|
irq_mask_reg <= cpu_data_w(7 downto 0);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
if (irq_status and irq_mask_reg) /= ZERO(7 downto 0) then
|
|
irq <= '1';
|
|
else
|
|
irq <= '0';
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-- RAM
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
cs_ram <= '1' when address_next(30 downto 28) = "000" else '0';
|
|
ram_address(31 downto 2) <= ZERO(31 downto 13) & address_next(12 downto 2);
|
|
|
|
u2_ram: ram
|
|
generic map (memory_type => memory_type)
|
|
port map (
|
|
clk => clk,
|
|
enable => cs_ram,
|
|
write_byte_enable => byte_we_next,
|
|
address => ram_address,
|
|
data_write => cpu_data_w,
|
|
data_read => ram_data_r);
|
|
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-- UART
|
|
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
u3_uart: uart
|
|
generic map (log_file => log_file)
|
|
port map(
|
|
clk => clk,
|
|
reset => reset,
|
|
cs => cs_uart,
|
|
nRdWr => cpu_byte_we(0),
|
|
data_in => cpu_data_w(7 downto 0),
|
|
data_out => data_read_uart,
|
|
uart_read => uart_read,
|
|
uart_write => uart_write,
|
|
busy_write => uart_write_busy,
|
|
data_avail => uart_data_avail);
|
|
|
|
end; --architecture logic
|
|
|