📄 vdp_pack.vhd
字号:
-- package of procedures to support testing of VDP
-- Thomas Clarke, 2001
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE std.textio.ALL;
USE work.utility_pack.ALL;
PACKAGE vdp_pack IS
--------------------------------------------------------------------------
----------------------------- behavioural vram ----------------------------
--------------------------------------------------------------------------
CONSTANT screen_width : INTEGER := 64; -- dimensions of screen
-- must not be changed
CONSTANT rsize : INTEGER := (screen_width*screen_width)/16;
-- number of vram words
-- times that characterise vram
CONSTANT taws : TIME := 25 ns;
CONSTANT twp : TIME := 25 ns;
CONSTANT twds : TIME := 10 ns;
CONSTANT tracc : TIME := 50 ns;
TYPE ram_array IS ARRAY (0 TO rsize-1) OF STD_LOGIC_VECTOR(15 DOWNTO 0);
SHARED VARIABLE ram_data : ram_array; -- state for vram entity ram
SHARED VARIABLE ram_data_model : ram_array; -- parallel state for use by testbench
-- controls do_ram_cycle operation
TYPE ram_mode_type IS (
vram, -- use process ramio in vdp_behav to generate ram I/O signals
-- these cause ram_data vraiable (in vram) to be read/written
-- see vram entity
vram_behav, -- reads/writes to ram_data directly
model -- reads/writes to ram_data_model directly
);
-- I/O for vram, allows procedure that implements ram I/O cycles
-- and used only two signal parameters (cycle_init and cycle_done)
SHARED VARIABLE vaddr_v : INTEGER;
SHARED VARIABLE vdin_v : STD_LOGIC_VECTOR(15 DOWNTO 0);
SHARED VARIABLE vdout_v : STD_LOGIC_VECTOR(15 DOWNTO 0);
SHARED VARIABLE vwrite_v : BOOLEAN;
-- implements a RAM read or write cycle using the above paras
-- data is written and read via ram_io process
PROCEDURE do_ram_cycle(
SIGNAL cycle_init : OUT STD_LOGIC; -- 0->1 starts cycle
SIGNAL cycle_done : IN STD_LOGIC; -- 0->1 flags end of cycle
destination : IN ram_mode_type
);
-- write a single bit at given x,y coordinates to ram
-- using the hardware ram interface
PROCEDURE write_ram_bit(
x : IN INTEGER;
y : IN INTEGER;
b : IN STD_LOGIC;
SIGNAL cycle_init : OUT STD_LOGIC;
SIGNAL cycle_done : IN STD_LOGIC;
dest : IN ram_mode_type
);
-- as above but read a single bit
PROCEDURE read_ram_bit(
x : IN INTEGER;
y : IN INTEGER;
SIGNAL cycle_init : OUT STD_LOGIC;
SIGNAL cycle_done : IN STD_LOGIC;
dest : IN ram_mode_type;
VARIABLE val : OUT STD_LOGIC
);
-- read a ram bit without using hardware interface, accessing
-- shared variable state directly
IMPURE FUNCTION read_ram_bit_direct(
x : IN INTEGER;
y : IN INTEGER;
ram : IN ram_array)
RETURN STD_LOGIC;
-- init ram to all '0' using shared variable state directly
PROCEDURE clear_ram_direct (VARIABLE ram : OUT ram_array);
-- print to transcript plot of ram contents, read
-- from state variables directly (no hardware cycles).
PROCEDURE display_ram( VARIABLE ram : IN ram_array;
window_size : IN INTEGER
);
---------------------------------------------------------------------------
-----------------------------behavioural host ------------------------------
---------------------------------------------------------------------------
TYPE pen_type IS( black,
white,
invert
);
TYPE cmd_type IS ( movepen,
drawline,
clearscreen,
flushcache
);
-- convert 16 bit command vector into its constituent fields
PROCEDURE decode_paras(
cmdword : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
VARIABLE cmd : OUT cmd_type;
VARIABLE x : OUT INTEGER;
VARIABLE y : OUT INTEGER;
VARIABLE pen : OUT pen_type
);
-- drive the HDB with a command which has parameters as specified
-- procedure will return when command has been successfully
-- output on (hdb, dav, hdb_busy)
PROCEDURE send_vdp_command(
-- command parameters
x : INTEGER; y : INTEGER; pen : pen_type; cmd : cmd_type;
-- host bus I/O signals
SIGNAL hdb : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL dav : OUT STD_LOGIC;
SIGNAL hdb_busy : IN STD_LOGIC
);
-- drive behavioural simulation of VDP with specified command
-- output is a sequence of calls to do_ram_cycle that use the
-- cycle_init/cycle_done interface to trigger vram cycles that
-- write as specified by the command.
PROCEDURE do_vdp_command(
cmd : IN cmd_type;
x : IN INTEGER;
y : IN INTEGER;
pen : IN pen_type;
SIGNAL cycle_init : OUT STD_LOGIC;
SIGNAL cycle_done : IN STD_LOGIC;
dest : IN ram_mode_type
);
-- reads file fname and interprets each line as a VDP command.
-- executes commands using do_vdp_command
PROCEDURE run_command_file(
fname : IN STRING;
SIGNAL cycle_init : OUT STD_LOGIC;
SIGNAL cycle_done : IN STD_LOGIC
);
-- writes out sample text file fname that contains
-- VDP commands in run_command_file format that draw
-- a star.
PROCEDURE write_lines(fname : IN STRING);
END PACKAGE vdp_pack;
--------------------------------------------------------------------
--------------------------------------------------------------------
---------------PACKAGE BODY -----------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
PACKAGE BODY vdp_pack IS
-----------------------------------------------------------------
------------------------behavioural vram-------------------------
-----------------------------------------------------------------
PROCEDURE do_ram_cycle(
SIGNAL cycle_init : OUT STD_LOGIC;
SIGNAL cycle_done : IN STD_LOGIC;
destination : ram_mode_type
) IS
BEGIN
CASE destination IS
-- write to model ram state
-- used to generate behav VRAM state to compare with real thing
WHEN model =>
-- don't use vram hardware, use ram_data_model state variable
IF vwrite_v THEN
ram_data_model(vaddr_v) := vdin_v;
ELSE
vdout_v := ram_data_model(vaddr_v);
END IF;
-- write to VRAM directly using shared variable state
WHEN vram_behav =>
IF vwrite_v THEN
ram_data(vaddr_v) := vdin_v;
ELSE
vdout_v := ram_data(vaddr_v);
END IF;
-- write to hardware VRAM using process ramio in vdp_behav
-- to do actual I/O
WHEN vram =>
cycle_init <= '0';
WAIT FOR 0 ns;
cycle_init <= '1';
WAIT UNTIL cycle_done'EVENT AND cycle_done = '1';
END CASE;
END do_ram_cycle;
PROCEDURE write_ram_bit(
x : IN INTEGER;
y : IN INTEGER;
b : IN STD_LOGIC;
SIGNAL cycle_init : OUT STD_LOGIC;
SIGNAL cycle_done : IN STD_LOGIC;
dest : IN ram_mode_type
) IS
-- writes pixel (x,y)
VARIABLE bitnum : INTEGER;
VARIABLE locnum : INTEGER;
BEGIN
bitnum := (x MOD 4) + 4*(y MOD 4);
vaddr_v := (x/4)+(y/4)*(screen_width/4);
vwrite_v := false;
do_ram_cycle(cycle_init, cycle_done, dest);
vdin_v := vdout_v;
vdin_v(bitnum) := b;
vwrite_v := true;
do_ram_cycle( cycle_init, cycle_done, dest);
END write_ram_bit;
PROCEDURE read_ram_bit(
x : IN INTEGER;
y : IN INTEGER;
SIGNAL cycle_init : OUT STD_LOGIC;
SIGNAL cycle_done : IN STD_LOGIC;
dest : IN ram_mode_type;
VARIABLE val : OUT STD_LOGIC
) IS
-- reads pixel (x,y) from ram
-- value returned is '0' (white) or '1' (black)
VARIABLE bitnum : INTEGER;
BEGIN
bitnum := (x MOD 4) + 4*(y MOD 4);
vaddr_v := (x/4)+(y/4)*(screen_width/4);
vwrite_v := false;
do_ram_cycle( cycle_init, cycle_done, dest);
val := vdout_v(bitnum);
END read_ram_bit;
PROCEDURE write_ram_bit_direct(
x : IN INTEGER;
y : IN INTEGER;
b : IN STD_LOGIC;
VARIABLE ram : OUT ram_array) IS
-- writes pixel (x,y)
VARIABLE bitnum : INTEGER;
VARIABLE locnum : INTEGER;
BEGIN
bitnum := (x MOD 4) + 4*(y MOD 4);
locnum := (x/4)+(y/4)*(screen_width/4);
ram(locnum)(bitnum) := b;
END write_ram_bit_direct;
IMPURE FUNCTION read_ram_bit_direct(
x : IN INTEGER;
y : IN INTEGER;
ram : IN ram_array)
RETURN STD_LOGIC IS
-- reads pixel (x,y) from ram
-- value returned is '0' (white) or '1' (black)
VARIABLE bitnum : INTEGER;
VARIABLE locnum : INTEGER;
BEGIN
bitnum := (x MOD 4) + 4*(y MOD 4);
locnum := (x/4)+(y/4)*(screen_width/4);
RETURN ram(locnum)(bitnum);
END read_ram_bit_direct;
PROCEDURE clear_ram_direct( VARIABLE ram : OUT ram_array) IS
-- this procedure clears ram to an initial colour of all black
BEGIN
FOR i IN ram'RANGE LOOP
ram(i) := (OTHERS => '0');
END LOOP;
END;
PROCEDURE display_ram( VARIABLE ram : IN ram_array;
window_size : IN INTEGER
) IS
-- this procedure displays the contents of ram on
-- the transcript, as a 64*64 block of characters
-- black is represented by *, white by +
-- the bottom left hand corner of the block
-- represents pixel (0,0)
VARIABLE buff : LINE;
VARIABLE ch : CHARACTER;
BEGIN
ASSERT window_size <= screen_width REPORT
"Window_size must be less than " & i2s(screen_width)
SEVERITY error;
FOR y IN window_size-1 DOWNTO 0 LOOP
FOR x IN 0 TO window_size-1 LOOP
CASE read_ram_bit_direct(x, y, ram) IS
WHEN '0' => ch := '*';
WHEN '1' => ch := '+';
WHEN 'U' => ch := 'U';
WHEN OTHERS => ch := 'X';
END CASE;
write( buff, ch);
END LOOP;
writeline( output, buff);
END LOOP;
END display_ram;
--------------------------------------------------------------
----------------------------behavioural host ----------------
--------------------------------------------------------------
-- code command parameters in 16 bit word and hanshake it onto
-- the VDP bus (hdb, dav, hdb_busy)
PROCEDURE send_vdp_command(
-- command parameters
x : INTEGER;
y : INTEGER;
pen : pen_type;
cmd : cmd_type;
-- host bus I/O signals
SIGNAL hdb : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -