Added some example for todo ghdl tooling flow support
All checks were successful
Run test asserts / Test-Asserts (push) Successful in 18s

This commit is contained in:
Willem Cazander 2025-05-05 11:20:37 +02:00
parent 855d5ca671
commit 7d7b134744
6 changed files with 730 additions and 0 deletions

View file

@ -0,0 +1,47 @@
EXAMPLE_VHDL_CHAIN_SRC := $(call mb-make-call,mb-make-module-path-src,$(PATH_SRC))
EXAMPLE_VHDL_CHAIN_BIN := $(call mb-make-call,mb-make-module-path-bin,$(PATH_SRC),$(PATH_BIN))
# TODO:
# project flow structure and ghdl tooling multiple work libs
define _mb-ghdl-analyze
$(MB_   )$(call mb-make-call,mb-make-check-arg2,$(0),$(1),$(2))
$(MB_   )cd $(1) && ghdl -a --work=zep_z80 --std=02 --ieee=synopsys ../../../$(2).vhdl
endef
define _mb-ghdl-extract
$(MB_   )$(call mb-make-call,mb-make-check-arg2,$(0),$(1),$(2))
$(MB_   )cd $(1) && ghdl -e --work=zep_z80 $(2)
endef
define _mb-ghdl-run
$(MB_   )$(call mb-make-call,mb-make-check-arg3,$(0),$(1),$(2),$(3))
$(MB_   )cd $(1) && ghdl -r --work=zep_z80 $(2) --wave=$(3)
endef
$(EXAMPLE_VHDL_CHAIN_BIN): # | @init
_$(MB_  )$(call mb-make-call,mb-os-dir-create,$(EXAMPLE_VHDL_CHAIN_BIN))
$(MB_   )$(call mb-make-call,mb-doc-target-deep,$(EXAMPLE_VHDL_CHAIN_BIN))
$(MB_   )$(call mb-make-call,mb-make-target-phony,$(EXAMPLE_VHDL_CHAIN_BIN))
$(EXAMPLE_VHDL_CHAIN_BIN)/@assert/@test/@z80-ctl-chain: $(EXAMPLE_VHDL_CHAIN_BIN)
_$(MB_  )$(call mb-make-call,mb-os-file-delete,$(EXAMPLE_VHDL_CHAIN_BIN)/zep_z80-obj93.cf)
_$(MB_  )$(call mb-make-call,mb-os-file-delete,$(EXAMPLE_VHDL_CHAIN_BIN)/work-wave.ghw)
_$(MB_  )$(call mb-make-call,_mb-ghdl-analyze,$(EXAMPLE_VHDL_CHAIN_BIN),$(EXAMPLE_VHDL_CHAIN_SRC)/z80_bus_package)
_$(MB_  )$(call mb-make-call,_mb-ghdl-analyze,$(EXAMPLE_VHDL_CHAIN_BIN),$(EXAMPLE_VHDL_CHAIN_SRC)/z80_bus_ctl_package)
_$(MB_  )$(call mb-make-call,_mb-ghdl-analyze,$(EXAMPLE_VHDL_CHAIN_BIN),$(EXAMPLE_VHDL_CHAIN_SRC)/z80_ctl_master)
_$(MB_  )$(call mb-make-call,_mb-ghdl-analyze,$(EXAMPLE_VHDL_CHAIN_BIN),$(EXAMPLE_VHDL_CHAIN_SRC)/z80_ctl_slave)
_$(MB_  )$(call mb-make-call,_mb-ghdl-analyze,$(EXAMPLE_VHDL_CHAIN_BIN),$(EXAMPLE_VHDL_CHAIN_SRC)/z80_ctl_chain_test)
_$(MB_  )$(call mb-make-call,_mb-ghdl-extract,$(EXAMPLE_VHDL_CHAIN_BIN),z80_ctl_chain_test)
_$(MB_  )$(call mb-make-call,_mb-ghdl-run,$(EXAMPLE_VHDL_CHAIN_BIN),z80_ctl_chain_test,work-wave.ghw)
_$(MB_  )$(call mb-make-call,mb-os-echo-assert,$(MB_I18N_ASSERT_SUCCESS) $(EXAMPLE_VHDL_CHAIN_BIN)/@assert/@test/@z80-ctl-chain)
$(MB_   )$(call mb-make-call,mb-doc-target-assert,$(EXAMPLE_VHDL_CHAIN_BIN)/@assert/@test/@z80-ctl-chain,Asserts z80 chain in VHDL.)
#$(MB_   )$(call mb-make-call,mb-proj-grow-deps-phase,@test,$(EXAMPLE_VHDL_CHAIN_BIN)/@assert/@test/@z80-ctl-chain)
$(MB_   )$(call mb-make-call,mb-make-target-phony,$(EXAMPLE_VHDL_CHAIN_BIN)/@assert/@test/@z80-ctl-chain)
$(EXAMPLE_VHDL_CHAIN_BIN)/@run: $(EXAMPLE_VHDL_CHAIN_BIN)/@assert/@test/@z80-ctl-chain
_$(MB_  )gtkwave $(EXAMPLE_VHDL_CHAIN_BIN)/work-wave.ghw
$(MB_   )$(call mb-make-call,mb-doc-target-run,$(EXAMPLE_VHDL_CHAIN_BIN)/@run,Run gtkwave to view test output.)
$(MB_   )$(call mb-make-call,mb-make-target-phony,$(EXAMPLE_VHDL_CHAIN_BIN)/@run)

View file

@ -0,0 +1,60 @@
library ieee;
use ieee.std_logic_1164.all;
library zep_z80;
use zep_z80.z80_bus_package.all;
package z80_bus_ctl_package is
-- slave of z80 bus
type stl_logic_z80_ctl_slave_out is record
z80 : stl_logic_z80_bus_slave;
ctl : stl_logic_z80_ctl_master;
end record stl_logic_z80_ctl_slave_out;
type stl_logic_z80_ctl_slave_in is record
z80 : stl_logic_z80_bus_master;
ctl : stl_logic_z80_ctl_slave;
end record stl_logic_z80_ctl_slave_in;
-- master of z80 bus
type stl_logic_z80_ctl_master_out is record
z80 : stl_logic_z80_bus_master;
ctl : stl_logic_z80_ctl_slave;
end record stl_logic_z80_ctl_master_out;
type stl_logic_z80_ctl_master_in is record
z80_io_twa : std_logic;
z80 : stl_logic_z80_bus_slave;
ctl : stl_logic_z80_ctl_master;
end record stl_logic_z80_ctl_master_in;
-- master of real tri-state phy z80 bus (note: not implemented)
type stl_logic_z80_ctl_master_phy_out is record
z80_cycle : stl_logic_z80_bus_cycle;
ctl : stl_logic_z80_ctl_master_out;
end record stl_logic_z80_ctl_master_phy_out;
type stl_logic_z80_ctl_master_phy_in is record
z80_sync : stl_logic_z80_bus_sync;
ctl : stl_logic_z80_ctl_master_in;
end record stl_logic_z80_ctl_master_phy_in;
type stl_logic_z80_ctl_master_phy_inout is record
z80_cmd : stl_logic_z80_bus_cmd;
z80_data : stl_logic_z80_bus_data;
z80_addr : stl_logic_z80_bus_addr;
end record stl_logic_z80_ctl_master_phy_inout;
component z80_ctl_master is
port (pin : in stl_logic_z80_ctl_master_in; put : out stl_logic_z80_ctl_master_out);
end component;
component z80_ctl_slave is
port (pin : in stl_logic_z80_ctl_slave_in; put : out stl_logic_z80_ctl_slave_out);
end component;
end z80_bus_ctl_package;

View file

@ -0,0 +1,113 @@
library ieee;
use ieee.std_logic_1164.all;
package z80_bus_package is
constant FINAL_Z80_BUS_DATA_WIDTH : integer := 8;
constant FINAL_Z80_BUS_ADDRESS_WIDTH : integer := 16;
subtype stl_logic_z80_bus_addr is std_logic_vector(FINAL_Z80_BUS_ADDRESS_WIDTH-1 downto 0);
subtype stl_logic_z80_bus_data is std_logic_vector(FINAL_Z80_BUS_DATA_WIDTH-1 downto 0);
-- tri-state: cmd + addr + data see: z80_bus_master_phy_package
type stl_logic_z80_bus_cmd is record
mreq_n : std_logic;
iorq_n : std_logic;
rd_n : std_logic;
wr_n : std_logic;
end record stl_logic_z80_bus_cmd;
type stl_logic_z80_bus_cycle is record
m1_n : std_logic;
rfsh_n : std_logic;
halt_n : std_logic;
busack_n : std_logic;
end record stl_logic_z80_bus_cycle;
type stl_logic_z80_bus_sync is record
wait_n : std_logic;
int_n : std_logic;
nmi_n : std_logic;
busreq_n : std_logic;
rst_n : std_logic;
clk : std_logic;
end record stl_logic_z80_bus_sync;
type stl_logic_z80_ctl_sync is record
rst : std_logic;
clk : std_logic;
end record stl_logic_z80_ctl_sync;
type stl_logic_z80_ctl_cmd is (
CTL_IDLE,
CTL_MEM_READ_M1,
CTL_MEM_READ,
CTL_MEM_WRITE,
CTL_IO_READ,
CTL_IO_WRITE,
CTL_HALT
);
type stl_logic_z80_bus_master is record
cycle : stl_logic_z80_bus_cycle;
cmd : stl_logic_z80_bus_cmd;
data : stl_logic_z80_bus_data;
addr : stl_logic_z80_bus_addr;
end record stl_logic_z80_bus_master;
type stl_logic_z80_bus_slave is record
sync : stl_logic_z80_bus_sync;
data : stl_logic_z80_bus_data;
end record stl_logic_z80_bus_slave;
type stl_logic_z80_ctl_master is record
cmd_rfsh : std_logic;
cmd_req : std_logic;
cmd : stl_logic_z80_ctl_cmd;
data : stl_logic_z80_bus_data;
addr : stl_logic_z80_bus_addr;
end record stl_logic_z80_ctl_master;
type stl_logic_z80_ctl_slave is record
sync : stl_logic_z80_ctl_sync;
req_int : std_logic;
req_nmi : std_logic;
cmd_rdy : std_logic;
data : stl_logic_z80_bus_data;
end record stl_logic_z80_ctl_slave;
type stl_logic_z80_bus_state is (
BUS_IDLE,
BUS_MEM_T1,
BUS_MEM_T2,
BUS_MEM_TW,
BUS_MEM_T3,
BUS_MEM_RFSH,
BUS_MEM_RFSH_DONE,
BUS_IO_T1,
BUS_IO_T2,
BUS_IO_TWA,
BUS_IO_TW,
BUS_IO_T3,
BUS_INTACK_T1,
BUS_INTACK_T2,
BUS_INTACK_TWA,
BUS_INTACK_TW,
BUS_INTACK_T3,
BUS_REQUEST_TLW,
BUS_REQUEST_TX,
BUS_REQUEST_DONE,
BUS_HALT,
BUS_RESET,
BUS_RESET_DONE
);
end z80_bus_package;

View file

@ -0,0 +1,182 @@
library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.ALL;
library zep_z80;
use zep_z80.z80_bus_ctl_package.all;
use zep_z80.z80_bus_package.all;
entity z80_ctl_chain_test is
end z80_ctl_chain_test;
architecture arch of z80_ctl_chain_test is
component z80_ctl_master port (pin : in stl_logic_z80_ctl_master_in; put : out stl_logic_z80_ctl_master_out); end component;
component z80_ctl_slave port (pin : in stl_logic_z80_ctl_slave_in; put : out stl_logic_z80_ctl_slave_out); end component;
-- input: u0 controller output: u3 controller
for test_u0: z80_ctl_master use entity zep_z80.z80_ctl_master;
for test_u1: z80_ctl_slave use entity zep_z80.z80_ctl_slave;
for test_u2: z80_ctl_master use entity zep_z80.z80_ctl_master;
for test_u3: z80_ctl_slave use entity zep_z80.z80_ctl_slave;
signal test_run : std_logic := '1';
signal test_clk : std_logic := '0';
signal test_u0_in : stl_logic_z80_ctl_master_in;
signal test_u0_out : stl_logic_z80_ctl_master_out;
signal test_u1_in : stl_logic_z80_ctl_slave_in;
signal test_u1_out : stl_logic_z80_ctl_slave_out;
signal test_u2_in : stl_logic_z80_ctl_master_in;
signal test_u2_out : stl_logic_z80_ctl_master_out;
signal test_u3_in : stl_logic_z80_ctl_slave_in;
signal test_u3_out : stl_logic_z80_ctl_slave_out;
begin
test_u0: z80_ctl_master port map (pin => test_u0_in, put => test_u0_out);
test_u1: z80_ctl_slave port map (pin => test_u1_in, put => test_u1_out);
test_u2: z80_ctl_master port map (pin => test_u2_in, put => test_u2_out);
test_u3: z80_ctl_slave port map (pin => test_u3_in, put => test_u3_out);
test_clk <= not test_clk and test_run after 2 ns;
test_u3_in.ctl.sync.clk <= test_clk;
test_u0_in.z80 <= test_u1_out.z80; -- cross z80
test_u1_in.z80 <= test_u0_out.z80;
test_u1_in.ctl <= test_u2_out.ctl; -- cross ctl
test_u2_in.ctl <= test_u1_out.ctl;
test_u2_in.z80 <= test_u3_out.z80; -- cross z80
test_u3_in.z80 <= test_u2_out.z80;
-- test_u3_in.ctl <= test_u2_out.ctl;
test_u0_in.z80_io_twa <= '1';
test_u2_in.z80_io_twa <= '1';
main: process
begin
test_u0_in.ctl.data <= X"00"; -- write
test_u0_in.ctl.addr <= X"0000";
test_u0_in.ctl.cmd <= CTL_IDLE;
test_u0_in.ctl.cmd_req <= '0';
test_u0_in.ctl.cmd_rfsh <= '0';
test_u3_in.ctl.data <= X"00";
test_u3_in.ctl.req_int <= '0';
test_u3_in.ctl.req_nmi <= '0';
test_u3_in.ctl.cmd_rdy <= '0';
test_u3_in.ctl.sync.rst <= '1';
wait for 20 ns;
test_u3_in.ctl.sync.rst <= '0';
wait for 20 ns;
assert false report "start mem_read_m1" severity note;
test_u0_in.ctl.addr <= X"2321";
test_u0_in.ctl.cmd <= CTL_MEM_READ_M1;
test_u0_in.ctl.cmd_req <= '1';
wait until test_u3_out.ctl.cmd_req = '1';
assert test_u3_out.ctl.cmd = CTL_MEM_READ_M1 report "mem_read_m1 cmd error: " & stl_logic_z80_ctl_cmd'image(test_u3_out.ctl.cmd);
assert test_u3_out.ctl.addr = X"2321" report "mem_read_m1 addr error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.addr)));
test_u3_in.ctl.data <= X"48";
test_u3_in.ctl.cmd_rdy <= '1';
test_u0_in.ctl.cmd_req <= '0';
wait until test_u0_out.ctl.cmd_rdy = '1';
assert test_u0_out.ctl.data = X"48" report "meme_read_m1 data error: " & integer'image(to_integer(unsigned(test_u0_out.ctl.data)));
test_u3_in.ctl.cmd_rdy <= '0';
wait for 10 ns;
assert false report "start mem_read" severity note;
test_u0_in.ctl.addr <= X"0001";
test_u0_in.ctl.cmd <= CTL_MEM_READ;
test_u0_in.ctl.cmd_req <= '1';
wait until test_u3_out.ctl.cmd_req = '1';
assert test_u3_out.ctl.cmd = CTL_MEM_READ report "mem_read cmd error: " & stl_logic_z80_ctl_cmd'image(test_u3_out.ctl.cmd);
assert test_u3_out.ctl.addr = X"0001" report "mem_read addr error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.addr)));
assert test_u3_out.ctl.data = X"F5" report "mem_read data error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.data)));
test_u3_in.ctl.cmd_rdy <= '1';
test_u0_in.ctl.cmd_req <= '0';
wait until test_u0_out.ctl.cmd_rdy = '1';
test_u3_in.ctl.cmd_rdy <= '0';
wait for 10 ns;
assert false report "start mem_read_rfsh" severity note;
test_u0_in.ctl.addr <= X"BBBB";
test_u0_in.ctl.cmd_rfsh <= '1';
wait until rising_edge(test_clk);
wait until falling_edge(test_clk);
test_u0_in.ctl.cmd_rfsh <= '0';
wait until test_u3_out.ctl.cmd_rfsh = '1';
wait for 10 ns;
assert false report "start mem_write" severity note;
test_u0_in.ctl.data <= X"F5";
test_u0_in.ctl.addr <= X"4321";
test_u0_in.ctl.cmd <= CTL_MEM_WRITE;
test_u0_in.ctl.cmd_req <= '1';
wait until test_u3_out.ctl.cmd_req = '1';
assert test_u3_out.ctl.cmd = CTL_MEM_WRITE report "mem_write cmd error: " & stl_logic_z80_ctl_cmd'image(test_u3_out.ctl.cmd);
assert test_u3_out.ctl.addr = X"4321" report "mem_write addr error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.addr)));
assert test_u3_out.ctl.data = X"F5" report "mem_write data error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.data)));
test_u3_in.ctl.cmd_rdy <= '1';
test_u0_in.ctl.cmd_req <= '0';
wait until test_u0_out.ctl.cmd_rdy = '1';
test_u3_in.ctl.cmd_rdy <= '0';
wait for 10 ns;
assert false report "start io_read" severity note;
test_u0_in.ctl.addr <= X"0038";
test_u0_in.ctl.cmd <= CTL_IO_READ;
test_u0_in.ctl.cmd_req <= '1';
wait until test_u3_out.ctl.cmd_req = '1';
wait for 10 ns;
assert test_u3_out.ctl.cmd = CTL_IO_READ report "io_read cmd error: " & stl_logic_z80_ctl_cmd'image(test_u3_out.ctl.cmd);
assert test_u3_out.ctl.addr = X"0038" report "io_read addr error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.addr)));
test_u3_in.ctl.data <= X"83";
test_u3_in.ctl.cmd_rdy <= '1';
test_u0_in.ctl.cmd_req <= '0';
wait until test_u0_out.ctl.cmd_rdy = '1';
assert test_u0_out.ctl.data = X"83" report "io_read data error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.data)));
test_u3_in.ctl.cmd_rdy <= '0';
wait for 10 ns;
assert false report "start io_write" severity note;
test_u0_in.ctl.data <= X"11";
test_u0_in.ctl.addr <= X"00A8";
test_u0_in.ctl.cmd <= CTL_IO_WRITE;
test_u0_in.ctl.cmd_req <= '1';
wait until test_u3_out.ctl.cmd_req = '1';
wait for 10 ns;
assert test_u3_out.ctl.cmd = CTL_IO_WRITE report "io_write cmd error: " & stl_logic_z80_ctl_cmd'image(test_u3_out.ctl.cmd);
assert test_u3_out.ctl.addr = X"00A8" report "io_write addr error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.addr)));
assert test_u3_out.ctl.data = X"11" report "io_write data error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.data)));
test_u3_in.ctl.cmd_rdy <= '1';
test_u0_in.ctl.cmd_req <= '0';
wait until test_u0_out.ctl.cmd_rdy = '1';
test_u3_in.ctl.cmd_rdy <= '0';
wait for 10 ns;
assert false report "start bus_halt" severity note;
test_u0_in.ctl.cmd <= CTL_HALT;
test_u0_in.ctl.cmd_req <= '1';
wait until test_u3_out.ctl.cmd_req = '1';
wait for 10 ns;
assert test_u3_out.ctl.cmd = CTL_HALT report "bus_halt cmd error: " & stl_logic_z80_ctl_cmd'image(test_u3_out.ctl.cmd);
-- assert test_u3_out.ctl.addr = X"00A8" report "io_write addr error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.addr)));
-- assert test_u3_out.ctl.data = X"11" report "io_write data error: " & integer'image(to_integer(unsigned(test_u3_out.ctl.data)));
test_u3_in.ctl.cmd_rdy <= '1';
test_u0_in.ctl.cmd_req <= '0';
-- wait until test_u0_out.ctl.cmd_rdy = '1';
test_u3_in.ctl.cmd_rdy <= '0';
wait for 10 ns;
wait for 100 ns;
assert false report "end of test" severity note;
test_run <= '0';
wait;
end process;
end arch;

View file

@ -0,0 +1,189 @@
library ieee;
use ieee.std_logic_1164.all;
library zep_z80;
use zep_z80.z80_bus_ctl_package.all;
use zep_z80.z80_bus_package.all;
entity z80_ctl_master is
port (pin : in stl_logic_z80_ctl_master_in; put : out stl_logic_z80_ctl_master_out);
end z80_ctl_master;
architecture behavioral of z80_ctl_master is
signal master_state : stl_logic_z80_bus_state;
signal master_ctl_cmd : stl_logic_z80_ctl_cmd;
signal master_ctl_addr : stl_logic_z80_bus_addr;
begin
put.ctl.sync.clk <= pin.z80.sync.clk;
put.z80.addr <= master_ctl_addr;
main : process(pin.z80.sync.clk)
begin
if rising_edge(pin.z80.sync.clk) then
if pin.z80.sync.rst_n = '0' then
master_state <= BUS_RESET;
master_ctl_cmd <= CTL_IDLE;
master_ctl_addr <= (others => '0');
put.z80.data <= (others => '0');
put.z80.cmd.iorq_n <= '1';
put.z80.cmd.mreq_n <= '1';
put.z80.cmd.wr_n <= '1';
put.z80.cmd.rd_n <= '1';
put.z80.cycle.m1_n <= '1';
put.z80.cycle.rfsh_n <= '1';
put.z80.cycle.halt_n <= '1';
put.z80.cycle.busack_n <= '1';
put.ctl.data <= (others => '0');
put.ctl.cmd_rdy <= '0';
put.ctl.req_int <= '0';
put.ctl.req_nmi <= '0';
put.ctl.sync.rst <= '1';
elsif master_state = BUS_IDLE and pin.ctl.cmd_req = '1' then
master_ctl_cmd <= pin.ctl.cmd;
master_ctl_addr <= pin.ctl.addr;
if master_state = BUS_IDLE and (pin.ctl.cmd = CTL_MEM_READ_M1 or pin.ctl.cmd = CTL_MEM_READ or pin.ctl.cmd = CTL_MEM_WRITE) then
master_state <= BUS_MEM_T1;
if pin.ctl.cmd = CTL_MEM_READ_M1 then
put.z80.cycle.m1_n <= '0'; -- note; M1 is set on rising clock of T1
end if;
elsif master_state = BUS_IDLE and (pin.ctl.cmd = CTL_IO_READ or pin.ctl.cmd = CTL_IO_WRITE) then
master_state <= BUS_IO_T1;
elsif master_state = BUS_IDLE and pin.ctl.cmd = CTL_HALT then
master_state <= BUS_HALT;
elsif master_state = BUS_HALT and (pin.z80.sync.int_n = '0' or pin.z80.sync.nmi_n = '0') then
master_state <= BUS_INTACK_T1;
end if;
elsif master_state = BUS_IDLE and pin.ctl.cmd_rfsh = '1' then
master_ctl_addr <= pin.ctl.addr;
master_state <= BUS_MEM_RFSH;
put.z80.cycle.rfsh_n <= '0';-- note: rfsh start in rising clock of T3
elsif master_state = BUS_MEM_T3 then
if pin.ctl.cmd = CTL_MEM_READ_M1 then
put.ctl.data <= pin.z80.data; -- note: M1 reads are on fising clock
put.z80.cycle.m1_n <= '1'; -- note; M1 is reset on rising clock of T3
put.z80.cmd.mreq_n <= '1';
put.z80.cmd.rd_n <= '1';
end if;
end if;
elsif falling_edge(pin.z80.sync.clk) then
case master_state is
when BUS_IDLE =>
put.z80.data <= (others => '0');
put.ctl.cmd_rdy <= '0';
when BUS_MEM_T1 =>
if master_ctl_cmd = CTL_MEM_WRITE then
put.z80.data <= pin.ctl.data;
else
put.z80.cmd.rd_n <= '0';
end if;
put.z80.cmd.mreq_n <= '0';
master_state <= BUS_MEM_T2;
when BUS_MEM_T2 =>
if master_ctl_cmd = CTL_MEM_WRITE then
put.z80.cmd.wr_n <= '0';
end if;
if pin.z80.sync.wait_n = '1' then
master_state <= BUS_MEM_T3;
else
master_state <= BUS_MEM_TW;
end if;
when BUS_MEM_TW =>
if pin.z80.sync.wait_n = '1' then
master_state <= BUS_MEM_T3;
end if;
when BUS_MEM_T3 =>
if master_ctl_cmd = CTL_MEM_READ then
put.ctl.data <= pin.z80.data;
put.z80.cmd.mreq_n <= '1';
put.z80.cmd.rd_n <= '1';
end if;
if master_ctl_cmd = CTL_MEM_WRITE then
put.z80.cmd.mreq_n <= '1';
put.z80.cmd.wr_n <= '1';
end if;
put.ctl.cmd_rdy <= '1';
master_state <= BUS_IDLE;
when BUS_MEM_RFSH =>
put.z80.cmd.mreq_n <= '0';
master_state <= BUS_MEM_RFSH_DONE;
when BUS_MEM_RFSH_DONE =>
put.z80.cmd.mreq_n <= '1';
put.z80.cycle.rfsh_n <= '1';
-- put.ctl.cmd_rdy <= '1';
master_state <= BUS_IDLE;
when BUS_IO_T1 =>
if master_ctl_cmd = CTL_IO_WRITE then
put.z80.cmd.wr_n <= '0';
put.z80.data <= pin.ctl.data;
else
put.z80.cmd.rd_n <= '0';
end if;
put.z80.cmd.iorq_n <= '0';
master_state <= BUS_IO_T2;
when BUS_IO_T2 =>
if pin.z80_io_twa = '1' then
master_state <= BUS_IO_TWA;
else
master_state <= BUS_IO_TW;
end if;
when BUS_IO_TWA =>
master_state <= BUS_IO_TW;
when BUS_IO_TW =>
if pin.z80.sync.wait_n = '1' then
master_state <= BUS_IO_T3;
end if;
when BUS_IO_T3 =>
if master_ctl_cmd = CTL_IO_READ then
put.ctl.data <= pin.z80.data;
end if;
put.z80.cmd.iorq_n <= '1';
put.z80.cmd.wr_n <= '1';
put.z80.cmd.rd_n <= '1';
put.ctl.cmd_rdy <= '1';
master_state <= BUS_IDLE;
when BUS_INTACK_T1 =>
-- TODO
if master_state = BUS_HALT then
put.z80.cycle.halt_n <= '1';
end if;
when BUS_INTACK_T2 => null;
when BUS_INTACK_TWA => null;
when BUS_INTACK_TW => null;
when BUS_INTACK_T3 => null;
when BUS_REQUEST_TLW =>
master_state <= BUS_REQUEST_TX;
when BUS_REQUEST_TX =>
put.z80.cycle.busack_n <= '0';
master_state <= BUS_REQUEST_DONE;
when BUS_REQUEST_DONE =>
put.z80.cycle.busack_n <= '1';
put.ctl.cmd_rdy <= '1';
master_state <= BUS_IDLE;
when BUS_HALT =>
put.z80.cycle.halt_n <= '0';
when BUS_RESET =>
master_state <= BUS_RESET_DONE;
when BUS_RESET_DONE =>
put.ctl.sync.rst <= '0';
put.ctl.cmd_rdy <= '0';
master_state <= BUS_IDLE;
end case;
end if;
end process main;
end behavioral;

View file

@ -0,0 +1,139 @@
library ieee;
use ieee.std_logic_1164.all;
library zep_z80;
use zep_z80.z80_bus_ctl_package.all;
use zep_z80.z80_bus_package.all;
entity z80_ctl_slave is
port (pin : in stl_logic_z80_ctl_slave_in; put : out stl_logic_z80_ctl_slave_out);
end z80_ctl_slave;
architecture behavioral of z80_ctl_slave is
signal slave_state : stl_logic_z80_bus_state;
signal slave_z80_cmd : stl_logic_z80_ctl_cmd;
signal slave_z80_addr : stl_logic_z80_bus_addr;
signal slave_cmd_req : std_logic;
begin
put.z80.sync.clk <= pin.ctl.sync.clk;
put.z80.sync.rst_n <= not pin.ctl.sync.rst;
put.ctl.addr <= slave_z80_addr;
put.ctl.cmd <= slave_z80_cmd;
put.ctl.cmd_req <= slave_cmd_req;
main : process(pin.ctl.sync.clk)
begin
if rising_edge(pin.ctl.sync.clk) then
if pin.ctl.sync.rst = '1' then
slave_state <= BUS_IDLE;
slave_z80_cmd <= CTL_IDLE;
slave_z80_addr <= (others => '0');
slave_cmd_req <= '0';
put.ctl.cmd_rfsh <= '0';
put.ctl.data <= (others => '0');
put.z80.data <= (others => '0');
put.z80.sync.wait_n <= '1';
put.z80.sync.int_n <= '1';
put.z80.sync.nmi_n <= '1';
put.z80.sync.busreq_n <= '1';
elsif slave_state = BUS_IDLE and pin.z80.cmd.mreq_n = '0' then
put.z80.sync.wait_n <= '0';
slave_z80_addr <= pin.z80.addr;
slave_state <= BUS_MEM_T2;
end if;
elsif falling_edge(pin.ctl.sync.clk) then
if slave_state = BUS_IDLE then
if pin.z80.cycle.m1_n = '0' then
put.z80.sync.wait_n <= '0';
slave_z80_addr <= pin.z80.addr;
slave_state <= BUS_MEM_T2;
slave_z80_cmd <= CTL_MEM_READ_M1;
slave_cmd_req <= '1';
elsif pin.z80.cmd.iorq_n = '0' then
put.z80.sync.wait_n <= '0';
slave_z80_addr <= pin.z80.addr;
slave_state <= BUS_IO_T2;
slave_cmd_req <= '1';
if pin.z80.cmd.rd_n = '0' then
slave_z80_cmd <= CTL_IO_READ;
else
slave_z80_cmd <= CTL_IO_WRITE;
put.ctl.data <= pin.z80.data;
end if;
elsif pin.z80.cycle.rfsh_n = '0' then
slave_z80_addr <= pin.z80.addr;
slave_state <= BUS_MEM_RFSH;
put.ctl.cmd_rfsh <= '1';
elsif pin.z80.cycle.halt_n = '0' then
slave_state <= BUS_HALT;
slave_z80_cmd <= CTL_HALT;
slave_cmd_req <= '1';
end if;
end if;
if slave_cmd_req = '1' then
slave_cmd_req <= '0'; -- pulse request
end if;
case slave_state is
when BUS_IDLE => null;
when BUS_MEM_T2 =>
if slave_z80_cmd = CTL_IDLE then
slave_cmd_req <= '1';
if pin.z80.cmd.rd_n = '0' then
slave_z80_cmd <= CTL_MEM_READ;
else
slave_z80_cmd <= CTL_MEM_WRITE;
put.ctl.data <= pin.z80.data;
end if;
end if;
slave_state <= BUS_MEM_TW;
when BUS_MEM_TW =>
if pin.ctl.cmd_rdy = '1' then
put.z80.sync.wait_n <= '1';
slave_state <= BUS_MEM_T3;
if slave_z80_cmd = CTL_MEM_READ or slave_z80_cmd = CTL_MEM_READ_M1 then
put.z80.data <= pin.ctl.data;
end if;
end if;
when BUS_MEM_T3 =>
if pin.z80.cmd.mreq_n = '1' then
slave_z80_cmd <= CTL_IDLE;
slave_state <= BUS_IDLE;
end if;
when BUS_MEM_RFSH =>
slave_state <= BUS_MEM_RFSH_DONE;
when BUS_MEM_RFSH_DONE =>
put.ctl.cmd_rfsh <= '0';
slave_z80_cmd <= CTL_IDLE;
slave_state <= BUS_IDLE;
when BUS_IO_T2 =>
slave_state <= BUS_IO_TW;
when BUS_IO_TW =>
if pin.ctl.cmd_rdy = '1' then
put.z80.sync.wait_n <= '1';
slave_state <= BUS_IO_T3;
if slave_z80_cmd = CTL_IO_READ then
put.z80.data <= pin.ctl.data;
end if;
end if;
when BUS_IO_T3 =>
if pin.z80.cmd.iorq_n = '1' then
slave_z80_cmd <= CTL_IDLE;
slave_state <= BUS_IDLE;
end if;
when BUS_HALT =>
if pin.ctl.cmd_rdy = '1' then
slave_state <= BUS_IDLE;
end if;
when others => null;
end case;
end if;
end process main;
end behavioral;