]> git.the-white-hart.net Git - vhdl/commitdiff
Add clock-optimized version of CPU0 project
authorRyan <>
Tue, 23 Sep 2025 16:18:42 +0000 (11:18 -0500)
committerRyan <>
Tue, 23 Sep 2025 16:18:42 +0000 (11:18 -0500)
projects/cpu_0/nexys2_speed.vhd [new file with mode: 0644]
projects/cpu_0/program.sh

diff --git a/projects/cpu_0/nexys2_speed.vhd b/projects/cpu_0/nexys2_speed.vhd
new file mode 100644 (file)
index 0000000..e639457
--- /dev/null
@@ -0,0 +1,588 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_misc.all;
+
+library utility;
+library nexys2_lib;
+library ps2;
+library rs232;
+library vga;
+library timer;
+
+
+entity nexys2_speed is
+       port (
+               -- Clock input
+               clk_50:     in    std_logic;
+
+               -- EPP interface
+               DB:         inout std_logic_vector(7 downto 0);
+               EppWRITE:   in    std_logic;
+               EppASTB:    in    std_logic;
+               EppDSTB:    in    std_logic;
+               EppWAIT:    out   std_logic;
+
+               -- Memory interface
+               MemOE:      out   std_logic;
+               MemWR:      out   std_logic;
+               RamAdv:     out   std_logic;
+               RamCS:      out   std_logic;
+               RamClk:     out   std_logic;
+               RamCRE:     out   std_logic;
+               RamLB:      out   std_logic;
+               RamUB:      out   std_logic;
+               RamWait:    in    std_logic;
+               FlashRp:    out   std_logic;
+               FlashCS:    out   std_logic;
+               FlashStSts: in    std_logic;
+               MemAdr:     out   std_logic_vector(23 downto 1);
+               MemDB:      inout std_logic_vector(15 downto 0);
+
+               -- Switches and LEDs
+               seg:        out   std_logic_vector(6 downto 0);
+               dp:         out   std_logic;
+               an:         out   std_logic_vector(3 downto 0);
+               Led:        out   std_logic_vector(7 downto 0);
+               sw:         in    std_logic_vector(7 downto 0);
+               btn:        in    std_logic_vector(3 downto 0);
+
+               -- VGA video output
+               vgaRed:     out   std_logic_vector(3 downto 1);
+               vgaGreen:   out   std_logic_vector(3 downto 1);
+               vgaBlue:    out   std_logic_vector(3 downto 2);
+               Hsync:      out   std_logic;
+               Vsync:      out   std_logic;
+
+               -- PS2 (keyboard)
+               PS2C:       inout std_logic;
+               PS2D:       inout std_logic;
+
+               -- RS232 (mouse)
+               RsRx:       in    std_logic;
+               RsTx:       out   std_logic
+       );
+end nexys2_speed;
+
+
+architecture behavioral of nexys2_speed is
+
+       -- Device Wishbone SYSCON
+       signal d_rst:             std_logic;  -- Device reset (P.O.R. or host)
+       signal d_clk:             std_logic;  -- Device clock, in case DCM used instead of clk_50 later
+
+       -- Wishbone busses
+       signal cyc:               std_logic;
+       signal stb:               std_logic;
+       signal we:                std_logic;
+       signal ack:               std_logic;
+       signal adr:               std_logic_vector(31 downto 0);
+       signal dat_mosi:          std_logic_vector(7 downto 0);
+       signal dat_miso:          std_logic_vector(7 downto 0);
+
+       signal fls_cyc:           std_logic;
+       signal ram_cyc:           std_logic;
+       signal mem_ack:           std_logic;
+       signal mem_miso:          std_logic_vector(7 downto 0);
+
+       signal bridge_a_cyc:      std_logic;
+       signal bridge_a_ack:      std_logic;
+       signal bridge_a_miso:     std_logic_vector(7 downto 0);
+       signal bridge_b_cyc:      std_logic;
+       signal bridge_b_stb:      std_logic;
+       signal bridge_b_we:       std_logic;
+       signal bridge_b_ack:      std_logic;
+       signal bridge_b_adr:      std_logic_vector(31 downto 0);
+       signal bridge_b_mosi:     std_logic_vector(7 downto 0);
+       signal bridge_b_miso:     std_logic_vector(7 downto 0);
+
+       signal scr_cyc:           std_logic;
+       signal tile_cyc:          std_logic;
+       signal pal_cyc:           std_logic;
+       signal vga_ack:           std_logic;
+       signal vga_miso:          std_logic_vector(7 downto 0);
+
+       signal host_cyc:          std_logic;
+       signal host_ack:          std_logic;
+       signal host_miso:         std_logic_vector(7 downto 0);
+
+       signal ps2_cyc:           std_logic;
+       signal ps2_ack:           std_logic;
+       signal ps2_miso:          std_logic_vector(7 downto 0);
+
+       signal uart_cyc:          std_logic;
+       signal uart_ack:          std_logic;
+       signal uart_miso:         std_logic_vector(7 downto 0);
+
+       signal timer0_cyc:        std_logic;
+       signal timer0_ack:        std_logic;
+       signal timer0_miso:       std_logic_vector(7 downto 0);
+
+       signal timer1_cyc:        std_logic;
+       signal timer1_ack:        std_logic;
+       signal timer1_miso:       std_logic_vector(7 downto 0);
+
+       -- Interrupt signals
+       signal host_flags:        std_logic_vector(7 downto 0);
+
+       signal ps2_rx_ready:      std_logic;
+       signal ps2_rx_full:       std_logic;
+       signal ps2_tx_ready:      std_logic;
+       signal ps2_tx_empty:      std_logic;
+       signal ps2_err_nack:      std_logic;
+       signal ps2_err_txto:      std_logic;
+       signal ps2_err_rxto:      std_logic;
+       signal ps2_err_missed:    std_logic;
+       signal ps2_err_parity:    std_logic;
+       signal ps2_err_framing:   std_logic;
+
+       signal uart_rx_ready:     std_logic;
+       signal uart_rx_full:      std_logic;
+       signal uart_tx_ready:     std_logic;
+       signal uart_tx_empty:     std_logic;
+       signal uart_err_break:    std_logic;
+       signal uart_err_framing:  std_logic;
+       signal uart_err_parity:   std_logic;
+       signal uart_err_overflow: std_logic;
+
+       signal timer0_zero:       std_logic;
+       signal timer1_zero:       std_logic;
+
+       -- Memory physical interface, routed through host controller
+       signal d_MemOE:           std_logic;
+       signal d_MemWR:           std_logic;
+       signal d_RamAdv:          std_logic;
+       signal d_RamCS:           std_logic;
+       signal d_RamClk:          std_logic;
+       signal d_RamCRE:          std_logic;
+       signal d_RamUB:           std_logic;
+       signal d_RamLB:           std_logic;
+       signal d_RamWait:         std_logic;
+       signal d_FlashRp:         std_logic;
+       signal d_FlashCS:         std_logic;
+       signal d_FlashStSts:      std_logic;
+       signal d_MemAdr:          std_logic_vector(23 downto 1);
+       signal d_MemDB_i:         std_logic_vector(15 downto 0);
+       signal d_MemDB_o:         std_logic_vector(15 downto 0);
+
+       -- Interrupt signals
+       signal int_cpu:           std_logic;
+       signal int_vec:           std_logic_vector(7 downto 0);
+       signal ints:              std_logic_vector(15 downto 0);
+
+       -- Debug signals
+       signal deb_wait:          std_logic;
+       signal deb_pc:            std_logic_vector(31 downto 0);
+       signal deb_ins:           std_logic_vector(7 downto 0);
+       signal deb_t:             std_logic_vector(31 downto 0);
+       signal deb_n:             std_logic_vector(31 downto 0);
+       signal deb_r:             std_logic_vector(31 downto 0);
+       signal debug_i:           std_logic_vector(63 downto 0);
+       signal debug_o:           std_logic_vector(63 downto 0);
+
+begin
+
+       e_cpu: entity work.cpu
+               port map (
+                       rst_i => d_rst,
+                       clk_i => d_clk,
+
+                       cyc_o => cyc,
+                       stb_o => stb,
+                       we_o  => we,
+                       ack_i => ack,
+                       adr_o => adr,
+                       dat_o => dat_mosi,
+                       dat_i => dat_miso,
+
+                       int_i => int_cpu,
+                       vec_i => int_vec,
+
+                       halt_i => sw(7),
+                       step_i => deb_wait,
+                       pc_o  => open,--deb_pc,
+                       ins_o => open,--deb_ins,
+                       t_o   => open,--deb_t,
+                       n_o   => open,--deb_n,
+                       r_o   => open--deb_r
+               );
+
+       deb_wait <= debug_i(0);
+       debug_o <= (others => '0');
+       --with debug_i(2 downto 1) select debug_o <=
+       --      x"000000" & deb_ins & deb_pc when "00",
+       --      deb_n & deb_t                when "01",
+       --      x"00000000" & deb_r          when others;
+
+       int_vec(7 downto 4) <= (others => '0');
+       ints(0) <= '0';
+       e_int: entity work.int_ctrl
+               port map (
+                       int_o => int_cpu,
+                       vec_o => int_vec(3 downto 0),
+                       int_i => ints
+               );
+
+       d_clk <= clk_50;
+
+
+       e_mapper_a: entity utility.wb_mapper_a32d8
+               generic map (N => 3)
+               port map (
+                       cyc_i    => cyc,
+                       ack_o    => ack,
+                       adr_i    => adr,
+                       dat_o    => dat_miso,
+
+                       mask(0)  => "00000011000000000000000000000000",  -- Flash
+                       mask(1)  => "00000011000000000000000000000000",  -- RAM
+                       mask(2)  => "00000010000000000000000000000000",  -- Bridge
+
+                       match(0) => "00000000000000000000000000000000",
+                       match(1) => "00000001000000000000000000000000",
+                       match(2) => "00000010000000000000000000000000",
+
+                       cyc_o(0) => fls_cyc,
+                       cyc_o(1) => ram_cyc,
+                       cyc_o(2) => bridge_a_cyc,
+
+                       ack_i(0) => mem_ack,
+                       ack_i(1) => mem_ack,
+                       ack_i(2) => bridge_a_ack,
+
+                       dat_i(0) => mem_miso,
+                       dat_i(1) => mem_miso,
+                       dat_i(2) => bridge_a_miso
+               );
+
+
+       e_bridge: entity utility.wb_bridge
+               generic map (A_WIDTH => 32, D_WIDTH => 8)
+               port map (
+                       rst_i   => d_rst,
+                       clk_i   => d_clk,
+
+                       a_cyc_i => bridge_a_cyc,
+                       a_stb_i => stb,
+                       a_we_i  => we,
+                       a_ack_o => bridge_a_ack,
+                       a_adr_i => adr,
+                       a_dat_i => dat_mosi,
+                       a_dat_o => bridge_a_miso,
+
+                       b_cyc_o => bridge_b_cyc,
+                       b_stb_o => bridge_b_stb,
+                       b_we_o  => bridge_b_we,
+                       b_ack_i => bridge_b_ack,
+                       b_adr_o => bridge_b_adr,
+                       b_dat_o => bridge_b_mosi,
+                       b_dat_i => bridge_b_miso
+               );
+
+       -- Flash:   0x00000000-0x00ffffff
+       -- Ram:     0x01000000-0x01ffffff
+       -- Vbuf:    0x02000000-0x02003fff
+       -- Tiles:   0x02004000-0x020047ff
+       -- Palette: 0x02006000-0x02007fff
+       -- Host:    0x02008000-0x02008007
+       -- PS2:     0x02008008-0x0200800f
+       -- UART:    0x02008010-0x02008017
+       -- Timer0:  0x02008018-0x0200801b
+       -- Timer1:  0x0200801c-0x0200801f
+       e_mapper_b: entity utility.wb_mapper_a32d8
+               generic map (N => 8)
+               port map (
+                       cyc_i    => bridge_b_cyc,
+                       ack_o    => bridge_b_ack,
+                       adr_i    => bridge_b_adr,
+                       dat_o    => bridge_b_miso,
+
+                       mask(0)  => "00000000000000001100000000000000",  -- VGA screen buffer
+                       mask(1)  => "00000000000000001110000000000000",  -- VGA tile memory
+                       mask(2)  => "00000000000000001110000000000000",  -- VGA palette
+                       mask(3)  => "00000000000000001100000000011000",  -- Host
+                       mask(4)  => "00000000000000001100000000011000",  -- PS2
+                       mask(5)  => "00000000000000001100000000011000",  -- UART
+                       mask(6)  => "00000000000000001100000000011100",  -- Timer0
+                       mask(7)  => "00000000000000001100000000011100",  -- Timer1
+
+                       match(0) => "00000000000000000000000000000000",  -- VGA scrbuf
+                       match(1) => "00000000000000000100000000000000",  -- VGA tiles
+                       match(2) => "00000000000000000110000000000000",  -- VGA palette
+                       match(3) => "00000000000000001000000000000000",
+                       match(4) => "00000000000000001000000000001000",
+                       match(5) => "00000000000000001000000000010000",
+                       match(6) => "00000000000000001000000000011000",
+                       match(7) => "00000000000000001000000000011100",
+
+                       cyc_o(0) => scr_cyc,
+                       cyc_o(1) => tile_cyc,
+                       cyc_o(2) => pal_cyc,
+                       cyc_o(3) => host_cyc,
+                       cyc_o(4) => ps2_cyc,
+                       cyc_o(5) => uart_cyc,
+                       cyc_o(6) => timer0_cyc,
+                       cyc_o(7) => timer1_cyc,
+
+                       ack_i(0) => vga_ack,
+                       ack_i(1) => vga_ack,
+                       ack_i(2) => vga_ack,
+                       ack_i(3) => host_ack,
+                       ack_i(4) => ps2_ack,
+                       ack_i(5) => uart_ack,
+                       ack_i(6) => timer0_ack,
+                       ack_i(7) => timer1_ack,
+
+                       dat_i(0) => vga_miso,
+                       dat_i(1) => vga_miso,
+                       dat_i(2) => vga_miso,
+                       dat_i(3) => host_miso,
+                       dat_i(4) => ps2_miso,
+                       dat_i(5) => uart_miso,
+                       dat_i(6) => timer0_miso,
+                       dat_i(7) => timer1_miso
+               );
+
+
+       e_mem: entity nexys2_lib.mem_wb8_0_opt
+               port map (
+                       rst_i       => d_rst,
+                       clk_i       => d_clk,
+
+                       -- Internal access
+                       fls_cyc_i   => fls_cyc,
+                       ram_cyc_i   => ram_cyc,
+                       stb_i       => stb,
+                       we_i        => we,
+                       ack_o       => mem_ack,
+                       adr_i       => adr(23 downto 0),
+                       dat_i       => dat_mosi,
+                       dat_o       => mem_miso,
+
+                       -- Configuration
+                       --wait_cycles => "01100",
+
+                       -- Memory interface
+                       MemOE       => d_MemOE,
+                       MemWR       => d_MemWR,
+                       RamAdv      => d_RamAdv,
+                       RamCS       => d_RamCS,
+                       RamClk      => d_RamClk,
+                       RamCRE      => d_RamCRE,
+                       RamUB       => d_RamUB,
+                       RamLB       => d_RamLB,
+                       RamWait     => d_RamWait,
+                       FlashRp     => d_FlashRp,
+                       FlashCS     => d_FlashCS,
+                       FlashStSts  => d_FlashStSts,
+                       MemAdr      => d_MemAdr,
+                       MemDB_i     => d_MemDB_i,
+                       MemDB_o     => d_MemDB_o
+               );
+
+
+       e_vga: entity vga.vga_tiler_opt
+               port map (
+                       rst_i      => d_rst,
+                       clk_i      => d_clk,
+
+                       -- Internal access to screen buffer and tile set
+                       scr_cyc_i  => scr_cyc,
+                       tile_cyc_i => tile_cyc,
+                       pal_cyc_i  => pal_cyc,
+                       stb_i      => bridge_b_stb,
+                       we_i       => bridge_b_we,
+                       ack_o      => vga_ack,
+                       adr_i      => bridge_b_adr(13 downto 0),
+                       dat_i      => bridge_b_mosi,
+                       dat_o      => vga_miso,
+
+                       vga_clk    => d_clk,  -- TODO: Plug this into a DCM
+
+                       -- External pins
+                       vgaRed     => vgaRed,
+                       vgaGreen   => vgaGreen,
+                       vgaBlue    => vgaBlue,
+                       Hsync      => Hsync,
+                       Vsync      => Vsync
+               );
+
+
+       ints(1) <= or_reduce(host_flags);
+       e_host: entity nexys2_lib.host_ctrl_opt
+               port map (
+                       clk_i        => d_clk,
+                       rst_i        => '0',
+
+                       -- Signals to the internal device
+                       d_rst_o      => d_rst,
+                       d_flags_o    => host_flags,
+                       debug_i      => debug_o,
+                       debug_o      => debug_i,
+
+                       -- Internal access to control registers
+                       d_cyc_i      => host_cyc,
+                       d_stb_i      => bridge_b_stb,
+                       d_we_i       => bridge_b_we,
+                       d_ack_o      => host_ack,
+                       d_adr_i      => bridge_b_adr(2 downto 0),
+                       d_dat_i      => bridge_b_mosi,
+                       d_dat_o      => host_miso,
+
+                       -- Internal memory interface, can be switched off to allow the host to control memory
+                       d_MemOE      => d_MemOE,
+                       d_MemWR      => d_MemWR,
+                       d_RamAdv     => d_RamAdv,
+                       d_RamCS      => d_RamCS,
+                       d_RamClk     => d_RamClk,
+                       d_RamCRE     => d_RamCRE,
+                       d_RamLB      => d_RamLB,
+                       d_RamUB      => d_RamUB,
+                       d_RamWait    => d_RamWait,
+                       d_FlashRp    => d_FlashRp,
+                       d_FlashCS    => d_FlashCS,
+                       d_FlashStSts => d_FlashStSts,
+                       d_MemAdr     => d_MemAdr,
+                       d_MemDB_o    => d_MemDB_o,
+                       d_MemDB_i    => d_MemDB_i,
+
+                       -- External pins
+                       EppAstb      => EppASTB,
+                       EppDstb      => EppDSTB,
+                       EppWr        => EppWRITE,
+                       EppDB        => DB,
+                       EppWait      => EppWAIT,
+
+                       MemOE        => MemOE,
+                       MemWR        => MemWR,
+                       RamAdv       => RamAdv,
+                       RamCS        => RamCS,
+                       RamClk       => RamClk,
+                       RamCRE       => RamCRE,
+                       RamLB        => RamLB,
+                       RamUB        => RamUB,
+                       RamWait      => RamWait,
+                       FlashRp      => FlashRp,
+                       FlashCS      => FlashCS,
+                       FlashStSts   => FlashStSts,
+                       MemAdr       => MemAdr,
+                       MemDB        => MemDB,
+
+                       seg          => seg,
+                       dp           => dp,
+                       an           => an,
+                       Led          => Led,
+                       sw           => sw
+               );
+
+
+       ints(2) <= ps2_rx_ready    or
+                  ps2_rx_full     or
+                  ps2_tx_ready    or
+                  ps2_tx_empty    or
+                  ps2_err_nack    or
+                  ps2_err_txto    or
+                  ps2_err_rxto    or
+                  ps2_err_missed  or
+                  ps2_err_parity  or
+                  ps2_err_framing;
+       e_ps2: entity ps2.ps2_host_wb_opt
+               port map (
+                       rst_i       => d_rst,
+                       clk_i       => d_clk,
+
+                       -- Internal access
+                       cyc_i       => ps2_cyc,
+                       stb_i       => bridge_b_stb,
+                       we_i        => bridge_b_we,
+                       ack_o       => ps2_ack,
+                       adr_i       => bridge_b_adr(2 downto 0),
+                       dat_i       => bridge_b_mosi,
+                       dat_o       => ps2_miso,
+
+                       -- Interrupt signals
+                       rx_ready    => ps2_rx_ready,
+                       rx_full     => ps2_rx_full,
+                       tx_ready    => ps2_tx_ready,
+                       tx_empty    => ps2_tx_empty,
+                       err_nack    => ps2_err_nack,
+                       err_txto    => ps2_err_txto,
+                       err_rxto    => ps2_err_rxto,
+                       err_missed  => ps2_err_missed,
+                       err_parity  => ps2_err_parity,
+                       err_framing => ps2_err_framing,
+
+                       -- External pins
+                       ps2_clk     => PS2C,
+                       ps2_data    => PS2D
+               );
+
+
+       ints(3) <= uart_rx_ready     or
+                  uart_rx_full      or
+                  uart_tx_ready     or
+                  uart_tx_empty     or
+                  uart_err_break    or
+                  uart_err_framing  or
+                  uart_err_overflow;
+       e_rs232: entity rs232.rs232_uart_opt
+               port map (
+                       rst_i        => d_rst,
+                       clk_i        => d_clk,
+
+                       -- Internal access
+                       cyc_i        => uart_cyc,
+                       stb_i        => bridge_b_stb,
+                       we_i         => bridge_b_we,
+                       ack_o        => uart_ack,
+                       adr_i        => bridge_b_adr(2 downto 0),
+                       dat_i        => bridge_b_mosi,
+                       dat_o        => uart_miso,
+
+                       -- Interrupt signals
+                       rx_ready     => uart_rx_ready,
+                       rx_full      => uart_rx_full,
+                       tx_ready     => uart_tx_ready,
+                       tx_empty     => uart_tx_empty,
+                       err_break    => uart_err_break,
+                       err_framing  => uart_err_framing,
+                       err_parity   => uart_err_parity,
+                       err_overflow => uart_err_overflow,
+
+                       -- External pins
+                       tx           => RsTx,
+                       rx           => RsRx
+               );
+
+
+       ints(4) <= timer0_zero;
+       e_timer0: entity timer.timer
+               port map (
+                       rst_i => d_rst,
+                       clk_i => d_clk,
+                       cyc_i => timer0_cyc,
+                       stb_i => bridge_b_stb,
+                       we_i  => bridge_b_we,
+                       ack_o => timer0_ack,
+                       adr_i => bridge_b_adr(1 downto 0),
+                       dat_i => bridge_b_mosi,
+                       dat_o => timer0_miso,
+                       zero  => timer0_zero
+               );
+
+
+       ints(5) <= timer1_zero;
+       e_timer1: entity timer.timer
+               port map (
+                       rst_i => d_rst,
+                       clk_i => d_clk,
+                       cyc_i => timer1_cyc,
+                       stb_i => bridge_b_stb,
+                       we_i  => bridge_b_we,
+                       ack_o => timer1_ack,
+                       adr_i => bridge_b_adr(1 downto 0),
+                       dat_i => bridge_b_mosi,
+                       dat_o => timer1_miso,
+                       zero  => timer1_zero
+               );
+
+end behavioral;
index 561bf2a4bf6bbb779d3b0b254b76b6094c8b7b3d..c5b760c7db899aad5509684d8011663ac0a942e7 100755 (executable)
@@ -1,4 +1,4 @@
 #!/usr/bin/env bash
 
-djtgcfg -d Nexys2 -i 0 -f nexys2_opt.bit prog
+djtgcfg -d Nexys2 -i 0 -f nexys2_speed.bit prog