Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
a05beb9ceThis file is pinned to the selected release. Download the original to open it in your design tool.
----------------------------------------------------------------------------------
-- Simplified environment for CPU debugging that ensures, that ISIM works
-- done in 2016 by sy2002
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.env1_globals.all;
entity cpu_debug is
port (
CLK : in std_logic; -- 100 MHz clock
RESET_N : in std_logic; -- CPU reset button (negative, i.e. 0 = reset)
-- 7 segment display: common anode and cathode
SSEG_AN : out std_logic_vector(7 downto 0); -- common anode: selects digit
SSEG_CA : out std_logic_vector(7 downto 0) -- cathode: selects segment within a digit
);
end cpu_debug;
architecture beh of cpu_debug is
-- QNICE CPU
component QNICE_CPU
port (
-- clock
CLK : in std_logic;
RESET : in std_logic;
WAIT_FOR_DATA : in std_logic; -- 1=CPU adds wait cycles while re-reading from bus
ADDR : out std_logic_vector(15 downto 0); -- 16 bit address bus
-- bidirectional 16 bit data bus
DATA_IN : in std_logic_vector(15 downto 0); -- receive data
DATA_OUT : out std_logic_vector(15 downto 0); -- send data
DATA_DIR : out std_logic; -- 1=DATA is sending, 0=DATA is receiving
DATA_VALID : out std_logic; -- while DATA_DIR = 1: DATA contains valid data
-- signals about the CPU state
HALT : out std_logic -- 1=CPU halted due to the HALT command, 0=running
);
end component;
-- ROM
component BROM is
generic (
FILE_NAME : string
);
port (
clk : in std_logic; -- read and write on rising clock edge
ce : in std_logic; -- chip enable, when low then zero on output
address : in std_logic_vector(14 downto 0); -- address is for now 15 bit hard coded
data : out std_logic_vector(15 downto 0); -- read data
busy : out std_logic -- 1=still executing, i.e. can drive CPU's WAIT_FOR_DATA
);
end component;
-- BLOCK RAM
component BRAM is
port (
clk : in std_logic; -- read and write on rising clock edge
ce : in std_logic; -- chip enable, when low then zero on output
address : in std_logic_vector(14 downto 0); -- address is for now 16 bit hard coded
we : in std_logic; -- write enable
data_i : in std_logic_vector(15 downto 0); -- write data
data_o : out std_logic_vector(15 downto 0); -- read data
busy : out std_logic -- 1=still executing, i.e. can drive CPU's WAIT_FOR_DATA
);
end component;
-- VGA 80x40 monoschrome screen
component vga_textmode
port (
reset : in std_logic; -- async reset
clk : in std_logic; -- system clock
clk50MHz : in std_logic; -- needs to be a 50 MHz clock
-- VGA registers
en : in std_logic; -- enable for reading from or writing to the bus
we : in std_logic; -- write to VGA's registers via system's data bus
reg : in std_logic_vector(3 downto 0); -- register selector
data : inout std_logic_vector(15 downto 0); -- system's data bus
-- VGA signals, monochrome only
R : out std_logic;
G : out std_logic;
B : out std_logic;
hsync : out std_logic;
vsync : out std_logic
);
end component;
-- TIL display emulation (4 digits)
component til_display is
port (
clk : in std_logic;
reset : in std_logic;
til_reg0_enable : in std_logic; -- data register
til_reg1_enable : in std_logic; -- mask register (each bit equals one digit)
data_in : in std_logic_vector(15 downto 0);
-- 7 segment display needs multiplexed approach due to common anode
SSEG_AN : out std_logic_vector(7 downto 0); -- common anode: selects digit
SSEG_CA : out std_logic_vector(7 downto 0) -- cathode: selects segment within a digit
);
end component;
component cycle_counter is
port (
clk : in std_logic; -- system clock
reset : in std_logic; -- async reset
-- cycle counter's registers
en : in std_logic; -- enable for reading from or writing to the bus
we : in std_logic; -- write to VGA's registers via system's data bus
reg : in std_logic_vector(1 downto 0); -- register selector
data : inout std_logic_vector(15 downto 0) -- system's data bus
);
end component;
-- multiplexer to control the data bus (enable/disable the different parties)
component mmio_mux is
port (
-- input from hardware
HW_RESET : in std_logic;
CLK : in std_logic;
-- input from CPU
addr : in std_logic_vector(15 downto 0);
data_dir : in std_logic;
data_valid : in std_logic;
cpu_halt : in std_logic;
-- let the CPU wait for data from the bus
cpu_wait_for_data : out std_logic;
-- ROM is enabled when the address is < $8000 and the CPU is reading
rom_enable : out std_logic;
ram_enable : out std_logic;
rom_busy : in std_logic;
ram_busy : in std_logic;
pore_rom_enable : out std_logic;
pore_rom_busy : in std_logic;
-- signals for peripheral devices
til_reg0_enable : out std_logic;
til_reg1_enable : out std_logic;
switch_reg_enable : out std_logic;
kbd_en : out std_logic;
kbd_we : out std_logic;
kbd_reg : out std_logic_vector(1 downto 0);
vga_en : out std_logic;
vga_we : out std_logic;
vga_reg : out std_logic_vector(3 downto 0);
uart_en : out std_logic;
uart_we : out std_logic;
uart_reg : out std_logic_vector(1 downto 0);
cyc_en : out std_logic;
cyc_we : out std_logic;
cyc_reg : out std_logic_vector(1 downto 0);
reset_pre_pore : out std_logic;
reset_post_pore : out std_logic
);
end component;
-- CPU control signals
signal cpu_addr : std_logic_vector(15 downto 0);
signal cpu_data : std_logic_vector(15 downto 0);
signal cpu_data_dir : std_logic;
signal cpu_data_valid : std_logic;
signal cpu_wait_for_data : std_logic;
signal cpu_halt : std_logic;
-- MMIO control signals
signal rom_enable : std_logic;
signal ram_enable : std_logic;
signal ram_busy : std_logic;
signal rom_busy : std_logic;
signal pore_rom_enable : std_logic;
signal pore_rom_busy : std_logic;
signal til_reg0_enable : std_logic;
signal til_reg1_enable : std_logic;
signal switch_reg_enable : std_logic;
signal kbd_en : std_logic;
signal kbd_we : std_logic;
signal kbd_reg : std_logic_vector(1 downto 0);
signal vga_en : std_logic;
signal vga_we : std_logic;
signal vga_reg : std_logic_vector(3 downto 0);
signal uart_en : std_logic;
signal uart_we : std_logic;
signal uart_reg : std_logic_vector(1 downto 0);
signal cyc_en : std_logic;
signal cyc_we : std_logic;
signal cyc_reg : std_logic_vector(1 downto 0);
signal reset_pre_pore : std_logic;
signal reset_post_pore : std_logic;
-- VGA control signals
signal vga_r : std_logic;
signal vga_g : std_logic;
signal vga_b : std_logic;
-- combined pre- and post pore reset
signal reset_ctl : std_logic;
begin
-- QNICE CPU
cpu : QNICE_CPU
port map (
CLK => CLK,
RESET => reset_ctl,
WAIT_FOR_DATA => cpu_wait_for_data,
ADDR => cpu_addr,
DATA => cpu_data,
DATA_DIR => cpu_data_dir,
DATA_VALID => cpu_data_valid,
HALT => cpu_halt
);
-- ROM: up to 64kB consisting of up to 32.000 16 bit words
rom : BROM
generic map (
FILE_NAME => ROM_FILE
)
port map (
clk => CLK,
ce => rom_enable,
address => cpu_addr(14 downto 0),
data => cpu_data,
busy => rom_busy
);
-- RAM: up to 64kB consisting of up to 32.000 16 bit words
ram : BRAM
port map (
clk => CLK,
ce => ram_enable,
address => cpu_addr(14 downto 0),
we => cpu_data_dir,
data_i => cpu_data,
data_o => cpu_data,
busy => ram_busy
);
-- PORE ROM: Power On & Reset Execution ROM
-- contains code that is executed during power on and/or during reset
-- MMIO is managing the PORE process
pore_rom : BROM
generic map (
FILE_NAME => PORE_ROM_FILE
)
port map (
clk => CLK,
ce => pore_rom_enable,
address => cpu_addr(14 downto 0),
data => cpu_data,
busy => pore_rom_busy
);
-- TIL display emulation (4 digits)
til_leds : til_display
port map (
clk => CLK,
reset => reset_ctl,
til_reg0_enable => til_reg0_enable,
til_reg1_enable => til_reg1_enable,
data_in => cpu_data,
SSEG_AN => SSEG_AN,
SSEG_CA => SSEG_CA
);
-- cycle counter
cyc : cycle_counter
port map (
clk => clk,
reset => reset_ctl,
en => cyc_en,
we => cyc_we,
reg => cyc_reg,
data => cpu_data
);
-- memory mapped i/o controller
mmio_controller : mmio_mux
port map (
HW_RESET => not RESET_N,
CLK => clk,
addr => cpu_addr,
data_dir => cpu_data_dir,
data_valid => cpu_data_valid,
cpu_wait_for_data => cpu_wait_for_data,
cpu_halt => cpu_halt,
rom_enable => rom_enable,
rom_busy => rom_busy,
ram_enable => ram_enable,
ram_busy => ram_busy,
pore_rom_enable => pore_rom_enable,
pore_rom_busy => pore_rom_busy,
til_reg0_enable => til_reg0_enable,
til_reg1_enable => til_reg1_enable,
switch_reg_enable => switch_reg_enable,
kbd_en => kbd_en,
kbd_we => kbd_we,
kbd_reg => kbd_reg,
vga_en => vga_en,
vga_we => vga_we,
vga_reg => vga_reg,
uart_en => uart_en,
uart_we => uart_we,
uart_reg => uart_reg,
cyc_en => cyc_en,
cyc_we => cyc_we,
cyc_reg => cyc_reg,
reset_pre_pore => reset_pre_pore,
reset_post_pore => reset_post_pore
);
-- generate the general reset signal
reset_ctl <= '1' when (reset_pre_pore = '1' or reset_post_pore = '1') else '0';
end beh;