OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/trunk/rtl/vhdl/clkunit2.vhd File deleted \ No newline at end of file
/trunk/rtl/vhdl/rxunit2.vhd File deleted \ No newline at end of file
/trunk/rtl/vhdl/txunit2.vhd File deleted \ No newline at end of file
/trunk/rtl/vhdl/testbench1.vhd
32,6 → 32,9
-- Version 1.0- 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
-- Version 1.1 - 25th Jan 2004 - John Kent
-- removed "test_alu" and "test_cc"
--
--===========================================================================--
 
library ieee;
62,8 → 65,6
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal cpu_irq : Std_Logic;
signal cpu_nmi : std_logic;
signal cpu_firq : Std_Logic;
118,9 → 119,7
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
firq: in std_logic
);
end component cpu09;
 
138,9 → 137,7
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
firq => cpu_firq
);
 
-- *** Test Bench - User Defined Section ***
/trunk/rtl/vhdl/keyboard.vhd
0,0 → 1,148
---------------------------------------------------------------------------------------
--
-- Author: John Kent
-- Date : April 2, 2004
-- Interface to John Clayton's PS2 keyboard
--
---------------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
 
entity keyboard is
port(
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic;
kbd_clk : inout std_logic;
kbd_data : inout std_logic
);
end keyboard;
 
architecture my_keyboard of keyboard is
 
signal kbd_stat : std_logic_vector(7 downto 0);
signal kbd_ctrl : std_logic_vector(7 downto 0);
signal kbd_scan_code : std_logic_vector(7 downto 0);
signal kbd_ascii_code : std_logic_vector(7 downto 0);
signal kbd_tx_data : std_logic_vector(7 downto 0);
signal kbd_tx_reg : std_logic_vector(7 downto 0);
signal kbd_read : std_logic;
signal kbd_write : std_logic;
signal kbd_write_ack : std_logic;
 
component ps2_keyboard_interface
port(
clk : in std_logic;
reset : in std_logic;
ps2_clk : inout std_logic;
ps2_data : inout std_logic;
rx_extended : out std_logic;
rx_released : out std_logic;
rx_shift_key_on : out std_logic;
-- rx_scan_code : out std_logic_vector(7 downto 0);
rx_ascii : out std_logic_vector(7 downto 0);
rx_data_ready : out std_logic; -- rx_read_o
rx_read : in std_logic; -- rx_read_ack_i
tx_data : in std_logic_vector(7 downto 0);
tx_write : in std_logic;
tx_write_ack : out std_logic;
tx_error_no_keyboard_ack : out std_logic
);
end component;
 
begin
 
my_ps2_keyboard_interface : ps2_keyboard_interface
port map(
clk => clk,
reset => rst,
ps2_clk => kbd_clk,
ps2_data => kbd_data,
rx_extended => kbd_stat(2),
rx_released => kbd_stat(3),
rx_shift_key_on => kbd_stat(4),
-- rx_scan_code => kbd_scan_code,
rx_ascii => kbd_ascii_code,
rx_data_ready => kbd_stat(0),
rx_read => kbd_read,
tx_data => kbd_tx_data,
tx_write => kbd_write,
tx_write_ack => kbd_write_ack,
tx_error_no_keyboard_ack => kbd_stat(5)
);
 
keyboard_strobe : process( clk, rst, cs, rw, kbd_stat )
begin
if( rst = '1' ) then
kbd_read <= '0';
elsif( clk'event and clk='0' ) then
if( cs='1' and rw='1' and addr='1' ) then
kbd_read <= '1';
elsif( kbd_stat(0)='1' ) then
kbd_read <= '0';
else
kbd_read <= kbd_read;
end if;
end if;
end process;
 
--
-- read keyboard registers
--
keyboard_read : process( clk, rst, cs, rw, addr )
begin
if( addr = '1' ) then
data_out <= kbd_ascii_code;
else
data_out <= kbd_stat;
end if;
end process;
 
--
-- Write to keyboard register
--
keyboard_write : process( clk, rst, cs, rw, addr, data_in, kbd_tx_reg,
kbd_write, kbd_write_ack )
begin
if(rst = '1' ) then
kbd_ctrl <= "00000000";
kbd_tx_reg <= "00000000";
kbd_write <= '0';
elsif( clk'event and clk='0' ) then
if( cs='1' and rw='0' ) then
if( addr='1' ) then
kbd_tx_reg <= data_in;
kbd_ctrl <= kbd_ctrl;
kbd_write <= '1';
else
kbd_tx_reg <= kbd_tx_reg;
kbd_ctrl <= data_in;
kbd_write <= kbd_write;
end if;
elsif( kbd_write_ack='1' ) then
kbd_write <= '0';
else
kbd_write <= kbd_write;
end if;
kbd_stat(1) <= not kbd_write;
end if;
end process;
 
keyboard_interrupt : process( kbd_ctrl, kbd_stat )
begin
kbd_stat(6) <= kbd_ctrl(6);
kbd_stat(7) <= kbd_ctrl(7) and kbd_stat(0);
irq <= kbd_stat(7);
end process;
end my_keyboard;
 
/trunk/rtl/vhdl/cpu09.vhd
36,6 → 36,52
-- Initial release to Open Cores
-- reversed clock edge
--
-- Version 1.1 - 29 November 2003 John kent
-- ACCA and ACCB indexed offsets are 2's complement.
-- ALU Right Mux now sign extends ACCA & ACCB offsets
-- Absolute Indirect addressing performed a read on the
-- second byte of the address rather than a fetch
-- so it formed an incorrect address. Now fixed.
--
-- Version 1.2 - 29 November 2003 John Kent
-- LEAX and LEAY affect the Z bit only
-- LEAS and LEAU do not affect any condition codes
-- added an extra ALU control for LEA.
--
-- Version 1.3 - 12 December 2003 John Kent
-- CWAI did not work, was missed a PUSH_ST on calling
-- the ANDCC_STATE. Thanks go to Ghassan Kraidy for
-- finding this fault.
--
-- Version 1.4 - 12 December 2003 John Kent
-- Missing cc_ctrl assignment in otherwise case of
-- lea_state resulted in cc_ctrl being latched in
-- that state.
-- The otherwise statement should never be reached,
-- and has been fixed simply to resolve synthesis warnings.
--
-- Version 1.5 - 17 january 2004 John kent
-- The clear instruction used "alu_ld8" to control the ALU
-- rather than "alu_clr". This mean the Carry was not being
-- cleared correctly.
--
-- Version 1.6 - 24 January 2004 John Kent
-- Fixed problems in PSHU instruction
--
-- Version 1.7 - 25 January 2004 John Kent
-- removed redundant "alu_inx" and "alu_dex'
-- Removed "test_alu" and "test_cc"
-- STD instruction did not set condition codes
-- JMP direct was not decoded properly
-- CLR direct performed an unwanted read cycle
-- Bogus "latch_md" in Page2 indexed addressing
--
-- Version 1.8 - 27 January 2004 John Kent
-- CWAI in decode1_state should increment the PC.
-- ABX is supposed to be an unsigned addition.
-- Added extra ALU function
-- ASR8 slightly changed in the ALU.
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
53,9 → 99,7
hold: in std_logic;
irq: in std_logic;
firq: in std_logic;
nmi: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
nmi: in std_logic
);
end;
 
208,13 → 252,12
type alu_type is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc,
alu_and, alu_ora, alu_eor,
alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
alu_inx, alu_dex,
alu_lsr16, alu_lsl16,
alu_ror8, alu_rol8,
alu_asr8, alu_asl8, alu_lsr8,
alu_andcc, alu_orcc, alu_sex, alu_tfr,
alu_andcc, alu_orcc, alu_sex, alu_tfr, alu_abx,
alu_seif, alu_sei, alu_see, alu_cle,
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa );
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_lea, alu_nop, alu_daa );
 
signal op_code: std_logic_vector(7 downto 0);
signal pre_code: std_logic_vector(7 downto 0);
943,9 → 986,17
when two_right =>
right <= "0000000000000010";
when acca_right =>
right <= "00000000" & acca;
if acca(7) = '0' then
right <= "00000000" & acca(7 downto 0);
else
right <= "11111111" & acca(7 downto 0);
end if;
when accb_right =>
right <= "00000000" & accb;
if accb(7) = '0' then
right <= "00000000" & accb(7 downto 0);
else
right <= "11111111" & accb(7 downto 0);
end if;
when accd_right =>
right <= acca & accb;
when md_sign5_right =>
982,6 → 1033,8
when alu_adc | alu_sbc |
alu_rol8 | alu_ror8 =>
carry_in := cc(CBIT);
when alu_asr8 =>
carry_in := left(7);
when others =>
carry_in := '0';
end case;
1025,13 → 1078,13
 
case alu_ctrl is
when alu_add8 | alu_inc |
alu_add16 | alu_inx |
alu_adc =>
alu_add16 | alu_adc =>
out_alu <= left + right + ("000000000000000" & carry_in);
when alu_sub8 | alu_dec |
alu_sub16 | alu_dex |
alu_sbc =>
alu_sub16 | alu_sbc =>
out_alu <= left - right - ("000000000000000" & carry_in);
when alu_abx =>
out_alu <= left + ("00000000" & right(7 downto 0)) ;
when alu_and =>
out_alu <= left and right; -- and/bit
when alu_ora =>
1042,17 → 1095,15
out_alu <= left(14 downto 0) & carry_in; -- rol8/asl8/lsl16
when alu_lsr16 | alu_lsr8 =>
out_alu <= carry_in & left(15 downto 1); -- lsr
when alu_ror8 =>
out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror
when alu_asr8 =>
out_alu <= "00000000" & left(7) & left(7 downto 1); -- asr
when alu_ror8 | alu_asr8 =>
out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror8/asr8
when alu_neg =>
out_alu <= right - left; -- neg (right=0)
when alu_com =>
out_alu <= not left;
when alu_clr | alu_ld8 | alu_ld16 =>
when alu_clr | alu_ld8 | alu_ld16 | alu_lea =>
out_alu <= right; -- clr, ld
when alu_st8 | alu_st16 | alu_andcc | alu_orcc =>
when alu_st8 | alu_st16 | alu_andcc | alu_orcc | alu_tfr =>
out_alu <= left;
when alu_daa =>
out_alu <= left + ("00000000" & daa_reg);
1063,7 → 1114,7
out_alu <= "11111111" & left(7 downto 0);
end if;
when others =>
out_alu <= left; -- nop, tfr
out_alu <= left; -- nop
end case;
 
--
1107,8 → 1158,6
cc_out(CBIT) <= left(CBIT) and cc(CBIT);
when alu_orcc =>
cc_out(CBIT) <= left(CBIT) or cc(CBIT);
when alu_tfr =>
cc_out(CBIT) <= left(CBIT);
when others =>
cc_out(CBIT) <= cc(CBIT);
end case;
1127,8 → 1176,7
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
when alu_add16 | alu_sub16 |
alu_lsl16 | alu_lsr16 |
alu_inx | alu_dex |
alu_ld16 | alu_st16 =>
alu_ld16 | alu_st16 | alu_lea =>
cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or
out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or
out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
1137,8 → 1185,6
cc_out(ZBIT) <= left(ZBIT) and cc(ZBIT);
when alu_orcc =>
cc_out(ZBIT) <= left(ZBIT) or cc(ZBIT);
when alu_tfr =>
cc_out(ZBIT) <= left(ZBIT);
when others =>
cc_out(ZBIT) <= cc(ZBIT);
end case;
1162,8 → 1208,6
cc_out(NBIT) <= left(NBIT) and cc(NBIT);
when alu_orcc =>
cc_out(NBIT) <= left(NBIT) or cc(NBIT);
when alu_tfr =>
cc_out(NBIT) <= left(NBIT);
when others =>
cc_out(NBIT) <= cc(NBIT);
end case;
1178,8 → 1222,6
cc_out(IBIT) <= left(IBIT) or cc(IBIT);
when alu_seif | alu_sei =>
cc_out(IBIT) <= '1';
when alu_tfr =>
cc_out(IBIT) <= left(IBIT);
when others =>
cc_out(IBIT) <= cc(IBIT); -- interrupt mask
end case;
1196,8 → 1238,6
cc_out(HBIT) <= left(HBIT) and cc(HBIT);
when alu_orcc =>
cc_out(HBIT) <= left(HBIT) or cc(HBIT);
when alu_tfr =>
cc_out(HBIT) <= left(HBIT);
when others =>
cc_out(HBIT) <= cc(HBIT);
end case;
1241,8 → 1281,6
cc_out(VBIT) <= left(VBIT) and cc(VBIT);
when alu_orcc =>
cc_out(VBIT) <= left(VBIT) or cc(VBIT);
when alu_tfr =>
cc_out(VBIT) <= left(VBIT);
when others =>
cc_out(VBIT) <= cc(VBIT);
end case;
1252,8 → 1290,6
cc_out(FBIT) <= left(FBIT) and cc(FBIT);
when alu_orcc =>
cc_out(FBIT) <= left(FBIT) or cc(FBIT);
when alu_tfr =>
cc_out(FBIT) <= left(FBIT);
when alu_seif =>
cc_out(FBIT) <= '1';
when others =>
1265,8 → 1301,6
cc_out(EBIT) <= left(EBIT) and cc(EBIT);
when alu_orcc =>
cc_out(EBIT) <= left(EBIT) or cc(EBIT);
when alu_tfr =>
cc_out(EBIT) <= left(EBIT);
when alu_see =>
cc_out(EBIT) <= '1';
when alu_cle =>
1274,9 → 1308,6
when others =>
cc_out(EBIT) <= cc(EBIT);
end case;
 
test_alu <= out_alu;
test_cc <= cc_out;
end process;
 
------------------------------------
1819,7 → 1850,7
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
1969,7 → 2000,7
-- 6809 => 6 cycles
-- cpu09 => 5 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1
-- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
-- 3 md_lo=(ea) / pc=pc
-- 4 alu_left=md / md=alu_out / pc=pc
-- 5 (ea)=md_lo / pc=pc
1978,7 → 2009,7
-- 6809 => 3 cycles
-- cpu09 => 3 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1
-- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
-- 3 pc=ea
--
when "0000" =>
2000,7 → 2031,14
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= single_op_read_state;
case op_code(3 downto 0) is
when "1110" => -- jmp
next_state <= jmp_state;
when "1111" => -- clr
next_state <= single_op_exec_state;
when others =>
next_state <= single_op_read_state;
end case;
 
-- acca / accb inherent instructions
when "0001" =>
2474,7 → 2512,9
next_state <= pull_return_hi_state;
 
--
-- abx - add accb to index register
-- add accb to index register
-- *** Note: this is an unsigned addition.
-- does not affect any condition codes
-- 6809 => 3 cycles
-- cpu09 => 2 cycles
-- 1 op=(pc) / pc=pc+1
2483,7 → 2523,7
when "1010" => -- abx
left_ctrl <= ix_left;
right_ctrl <= accb_right;
alu_ctrl <= alu_add16;
alu_ctrl <= alu_abx;
cc_ctrl <= latch_cc;
ix_ctrl <= load_ix;
--
2515,7 → 2555,7
return_state <= fetch_state;
next_state <= rti_cc_state;
 
when "1100" => -- cwai
when "1100" => -- cwai #$<cc_mask>
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
2523,13 → 2563,13
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
pc_ctrl <= latch_pc;
pc_ctrl <= incr_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
st_ctrl <= push_st;
return_state <= int_entire_state; -- set entire flag
next_state <= andcc_state;
 
2665,7 → 2705,7
alu_ctrl <= alu_st8;
acca_ctrl <= latch_acca;
cc_ctrl <= load_cc;
when "1110" => -- jmp
when "1110" => -- jmp (not defined)
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
acca_ctrl <= latch_acca;
2672,7 → 2712,7
cc_ctrl <= latch_cc;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
alu_ctrl <= alu_clr;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when others =>
2760,7 → 2800,7
alu_ctrl <= alu_st8;
accb_ctrl <= latch_accb;
cc_ctrl <= load_cc;
when "1110" => -- jmp
when "1110" => -- jmp (undefined)
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
accb_ctrl <= latch_accb;
2767,7 → 2807,7
cc_ctrl <= latch_cc;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
alu_ctrl <= alu_clr;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when others =>
3465,7 → 3505,7
next_state <= dual_op_read16_state;
 
when "1111" => -- sty <
st_ctrl <= push_st;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
3599,7 → 3639,7
next_state <= dual_op_read16_state;
 
when "1111" => -- sts <
st_ctrl <= push_st;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
3617,7 → 3657,6
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
4042,7 → 4081,7
when "1111" => -- clr
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
alu_ctrl <= alu_clr;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
4350,7 → 4389,7
next_state <= saved_state;
 
--
-- ea holds 8 bit index offet
-- md & ea holds 8 bit index offset
-- calculate the effective memory address
-- using the alu
--
5225,6 → 5264,37
next_state <= indirect_state;
end if;
 
-- indexed to address
-- pick up the low byte of the address
-- advance the pc
when indexaddr_state =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
-- advance pc
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
pc_ctrl <= incr_pc;
-- fetch low byte
ea_ctrl <= latch_ea;
md_ctrl <= fetch_next_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indexaddr2_state;
 
-- indexed to absolute address
-- md holds address
-- ea hold indexing mode byte
5262,36 → 5332,6
next_state <= indirect_state;
end if;
 
-- indexed to address
-- pick up the low byte of the address
-- advance the pc
when indexaddr_state =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- advance pc
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
pc_ctrl <= incr_pc;
-- fetch low byte
md_ctrl <= fetch_next_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indexaddr2_state;
--
-- load md with high byte of indirect address
-- pointed to by ea
5424,7 → 5464,6
 
when lea_state => -- here on load effective address
op_ctrl <= latch_op;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
dp_ctrl <= latch_dp;
5437,29 → 5476,34
-- load index register with effective address
left_ctrl <= pc_left;
right_ctrl <= ea_right;
alu_ctrl <= alu_ld16;
alu_ctrl <= alu_lea;
case op_code(3 downto 0) is
when "0000" => -- leax
cc_ctrl <= load_cc;
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0001" => -- leay
cc_ctrl <= load_cc;
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0010" => -- leas
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
when "0011" => -- leau
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
cc_ctrl <= latch_cc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
7556,8 → 7600,8
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- decrement sp if any registers to be pushed
left_ctrl <= sp_left;
-- decrement up if any registers to be pushed
left_ctrl <= up_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
if ea(7 downto 0) = "00000000" then
7609,13 → 7653,13
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- decrement sp
-- decrement up
left_ctrl <= up_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
up_ctrl <= load_up;
-- write pc low
addr_ctrl <= pushs_ad;
addr_ctrl <= pushu_ad;
dout_ctrl <= pc_lo_dout;
--
st_ctrl <= idle_st;
7637,7 → 7681,7
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- decrement sp
-- decrement up
left_ctrl <= up_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
8023,7 → 8067,7
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- idle sp
-- idle up
left_ctrl <= up_left;
right_ctrl <= one_right;
cc_ctrl <= latch_cc;
/trunk/rtl/vhdl/testbench2.vhd
32,6 → 32,9
-- Version 1.0- 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
-- Version 1.1 - 25th Jan 2004 - John Kent
-- removed "test_alu" and "test_cc"
--
--===========================================================================--
 
library ieee;
40,13 → 43,13
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
entity my_testbench2 is
end my_testbench2;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
architecture behavior of my_testbench2 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
59,8 → 62,6
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal cpu_irq : Std_Logic;
signal cpu_nmi : Std_Logic;
signal cpu_firq : std_logic;
242,9 → 243,7
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
firq: in std_logic
);
end component cpu09;
 
262,9 → 261,7
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
firq => cpu_firq
);
 
-- *** Test Bench - User Defined Section ***
/trunk/rtl/vhdl/testbench3.vhd
25,12 → 25,15
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- Version 0.1 - 12 Apr 2003 - John Kent
-- First version
--
-- Version 1.0 - 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
-- Version 1.1 - 26 Feb 2004 - John kent
-- removed test_alu and test_cc signals from
-- CPU component.
--===========================================================================--
 
library ieee;
39,13 → 42,13
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
entity my_testbench3 is
end my_testbench3;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
architecture behavior of my_testbench3 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
61,8 → 64,6
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
 
constant width : integer := 8;
constant memsize : integer := 64;
101,7 → 102,11
"00010111", "00011000", -- F82A - 1718 FDB $1718 ; IY
"00011001", "00011010", -- F82C - 191A FDB $191A ; UP
"11111000", "00000000", -- F82E - F800 FDB RESET ; PC
"11111000", "00000000", -- F830 - F800 STACK FDB RESET ; RESV
-- F830 STACK EQU *
--
-- Interrupt Cectors Start Here
--
"11111000", "00000000", -- F830 - F800 FDB RESET ; RESV
"11111000", "00001001", -- F832 - F809 FDB SWIVEC3 ; SWI3
"11111000", "00000111", -- F834 - F807 FDB SWIVEC2 ; SWI2
"11111000", "00000000", -- F836 - F800 fdb RESET ; FIRQ
124,9 → 129,7
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
firq: in std_logic
);
end component cpu09;
 
144,9 → 147,7
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
firq => cpu_firq
);
 
-- *** Test Bench - User Defined Section ***
/trunk/rtl/vhdl/testbench4.vhd
6,7 → 6,10
--
-- John Kent 12st April 2003
--
-- Version 1.1 - 25th Jan 2004 - John Kent
-- removed "test_alu" and "test_cc"
--
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
37,8 → 40,6
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_halt : Std_logic;
signal cpu_hold : Std_logic;
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal rom_data_out: Std_Logic_Vector(7 downto 0);
signal ram_data_out: Std_Logic_Vector(7 downto 0);
signal ram_cs : Std_Logic;
56,9 → 57,7
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
firq: in std_logic
);
end component;
 
95,9 → 94,7
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
firq => cpu_firq
);
 
 
/trunk/rtl/vhdl/testbench5.vhd
0,0 → 1,191
--===========================================================================----
--
-- T E S T B E N C H tesetbench3 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench5.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 3
-- Contains ROM to test interrupts
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0 - 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
-- Version 1.1 - 25th Jan 2004 - John Kent
-- removed "test_alu" and "test_cc"
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench5 is
end my_testbench5;
 
-------------------------------------------------------------------------------
-- Architecture for test bench for cpu09
-------------------------------------------------------------------------------
architecture behavior of my_testbench5 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal cpu_irq : std_Logic;
signal cpu_firq : std_logic;
signal cpu_nmi : std_logic;
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
 
constant width : integer := 8;
constant memsize : integer := 128;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
x"10", x"CE", x"F8", x"30", -- F800 - 10CE F830 RESET LDS #$F830
x"CE", x"20", x"00", -- F804 - CE 2000 LDU #$2000
x"8E", x"F8", x"02", -- F807 - 8E 5000 LDX #$F802
x"10", x"8E", x"80", x"00", -- F80A - 108E 8000 LDY #$8000
x"86", x"55", -- F80E - 86 55 LDA #$55
x"C6", x"F0", -- F810 - C6 F0 LDB #$F0
x"97", x"40", -- F812 - 97 40 STA <$40
x"B7", x"90", x"00", -- F814 - B7 9000 STA $9000
x"A7", x"09", -- F817 - A7 09 STA 9,X ($F80B)
x"A7", x"29", -- F819 - A7 29 STA 9,Y ($8009)
x"A7", x"49", -- F81B - A7 49 STA 9,U ($2009)
x"A7", x"69", -- F81D - A7 69 STA 9,S ($F839)
x"A7", x"80", -- F81F - A7 80 STA ,X+ ($F802)
x"A7", x"81", -- F821 - A7 81 STA ,X++ ($F803)
x"A7", x"91", -- F823 - A7 91 STA [,X++] ($2000)
x"A7", x"82", -- F825 - A7 82 STA ,-X ($F806)
x"A7", x"83", -- F827 - A7 83 STA ,--X ($F804)
x"A7", x"93", -- F829 - A7 93 STA [,--X] ($2000)
x"A7", x"84", -- F82B - A7 84 STA ,X ($F802)
x"A7", x"94", -- F82D - A7 94 STA [,X] ($F830)
x"A7", x"85", -- F82F - A7 85 STA B,X ($F7F2)
x"A7", x"95", -- F831 - A7 95 STA [B,X] ($01A7)
x"A7", x"86", -- F833 - A7 86 STA A,X ($F857)
x"A7", x"96", -- F835 - A7 96 STA [A,X] ($A78C)
x"A7", x"88", x"FF", -- F837 - A7 88 FF STA -1,X ($F831)
x"A7", x"88", x"01", -- F83A - A7 88 01 STA 1,X ($F833)
x"A7", x"98", x"FF", -- F83D - A7 98 FF STA [-1,X] ([$F801])
x"A7", x"98", x"01", -- F840 - A7 98 01 STA [1,X] ([$F803])
x"A7", x"89", x"FF", x"FF", -- F843 - A7 89 FFFF STA -1,X ($F801)
x"A7", x"89", x"00", x"01", -- F847 - A7 89 0001 STA 1,X ($F803)
x"A7", x"99", x"FF", x"FF", -- F84B - A7 99 FFFF STA [-1,X] ([$F801])
x"A7", x"99", x"00", x"01", -- F84F - A7 99 0001 STA [1,X] ([$F803])
x"A7", x"8B", -- F853 - A7 8B STA D,X ($4BF2)
x"A7", x"9B", -- F855 - A7 9B STA [D,X] ([$4BF2]))
x"A7", x"8C", x"FF", -- F857 - A7 8C FF STA -1,X ($F801)
x"A7", x"8C", x"01", -- F85A - A7 8C 01 STA 1,X ($F803)
x"A7", x"9C", x"FF", -- F85D - A7 9C FF STA [-1,X] ([$F801])
x"A7", x"9C", x"01", -- F860 - A7 9C 01 STA [1,X] ([$F803])
x"A7", x"8D", x"FF", x"FF", -- F863 - A7 8D FFFF STA -1,X ($F801)
x"A7", x"8D", x"00", x"01", -- F867 - A7 8D 0001 STA 1,X ($F803)
x"A7", x"9D", x"FF", x"FF", -- F86B - A7 9D FFFF STA [-1,X] ([$F801])
x"A7", x"9D", x"00", x"01", -- F86F - A7 9D 0001 STA [1,X] ([$F803])
x"A7", x"8F", x"A0", x"00", -- F873 - A7 8F A000 STA $A000
x"A7", x"9F", x"A0", x"00", -- F877 - A7 9F A000 STA [$A000]
x"7E", x"F8", x"00", -- F87B - 7E F800 JMP RESET
x"F8", x"00" -- F87E - F800 fdb RESET ; Reset
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(6 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/trunk/rtl/vhdl/System09.npl
1,37 → 1,49
JDF E
// Created by ISE ver 1.0
JDF G
// Created by Project Navigator ver 1.0
PROJECT System09
DESIGN system09 Normal
DEVKIT xc2s300e-6pq208
DESIGN system09
DEVFAM spartan2e
FLOW XST VHDL
STIMULUS testbench1.vhd Normal
STIMULUS testbench2.vhd Normal
STIMULUS testbench3.vhd Normal
STIMULUS System09_tb.vhd Normal
MODULE ioport.vhd
MODSTYLE ioport Normal
MODULE rxunit2.vhd
MODSTYLE rxunit Normal
MODULE txunit2.vhd
MODSTYLE txunit Normal
MODULE cpu09.vhd
MODSTYLE cpu09 Normal
MODULE clkunit2.vhd
MODSTYLE clkunit Normal
MODULE datram.vhd
MODSTYLE dat_ram Normal
MODULE timer.vhd
MODSTYLE timer Normal
MODULE System09.vhd
MODSTYLE system09 Normal
MODULE sbug.vhd
MODSTYLE boot_rom Normal
MODULE miniUART2.vhd
MODSTYLE miniuart Normal
 
DEVFAMTIME 315558000
DEVICE xc2s300e
DEVICETIME 315558000
DEVPKG pq208
DEVPKGTIME 315558000
DEVSPEED -6
DEVSPEEDTIME 315558000
DEVTOPLEVELMODULETYPE HDL
TOPLEVELMODULETYPETIME 0
DEVSYNTHESISTOOL XST (VHDL/Verilog)
SYNTHESISTOOLTIME 0
DEVSIMULATOR Modelsim
SIMULATORTIME 0
DEVGENERATEDSIMULATIONMODEL VHDL
GENERATEDSIMULATIONMODELTIME 0
STIMULUS testbench1.vhd
STIMULUS testbench2.vhd
STIMULUS testbench3.vhd
STIMULUS System09_tb.vhd
SOURCE ioport.vhd
SOURCE cpu09.vhd
SOURCE datram.vhd
SOURCE timer.vhd
SOURCE System09.vhd
SOURCE sbug_rom.vhd
STIMULUS testbench5.vhd
SOURCE miniUART3.vhd
SOURCE rxunit3.vhd
SOURCE txunit3.vhd
STIMULUS testbench6.vhd
SOURCE trap.vhd
SOURCE vdu8.vhd
SOURCE charrom.vhd
SOURCE ps2_keyboard.vhd
SOURCE ram2k.vhd
SOURCE keyboard.vhd
DEPASSOC my_system09 system09.ucf
[Normal]
p_impactConfigMode=xstvhd, spartan2e, Implementation.t_impactProgrammingTool, 1068866286, Boundary Scan
p_ModelSimSimRunTime_tbw=xstvhd, spartan2e, Bencher Waveform.t_MSimulateBehavioralVhdlModel, 315558000, 1000ns
[STATUS-ALL]
cpu09.ngcFile=ERRORS,0
[STRATEGY-LIST]
Normal=True, 1062166682
 
[Normal]
p_impactConfigMode=xstvhd, SPARTAN2E, Implementation.t_impactProgrammingTool, 1031246025, Slave Serial
Normal=True
/trunk/rtl/vhdl/testbench6.vhd
0,0 → 1,183
--===========================================================================----
--
-- T E S T B E N C H tesetbench3 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench6.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 6
-- Tests STS indexed
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0 - 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
-- Version 1.1 - 25th Jan 2004 - John Kent
-- removed "test_alu" and "test_cc"
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench6 is
end my_testbench6;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench6 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal cpu_irq : std_Logic;
signal cpu_firq : std_logic;
signal cpu_nmi : std_logic;
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
 
constant width : integer := 8;
constant memsize : integer := 64;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
x"10",x"CE", x"F8", x"30", -- F800 - 10CE F830 RET1 LDS #STACK
x"CE",x"B0",x"00", -- F804 - CE B000 LDU #$B000
x"10",x"EF",x"C8",x"00", -- F807 - 10EF C800 STS $00,U
x"12",x"12",x"12", -- F80B - 12 12 12
"00110011", -- F8OE - 33 FCB $33 ; ACCB
"00110100", -- F8OF - 34 FCB $34 ; DPR
"00110101", "00110110", -- F810 - 3536 FDB $3536 ; IX
"00110111", "00111000", -- F812 - 3738 FDB $3738 ; IY
"00111001", "00111010", -- F814 - 393A FDB $393A ; UP
"11111000", "00001001", -- F816 - F809 FDB SWI3VEC ; PC
"10100001", -- F818 - A1 STACK2 FCB $A1 ; CC
"00100010", -- F819 - 22 FCB $22 ; ACCA
"00100011", -- F81A - 23 FCB $23 ; ACCB
"00100100", -- F81B - 24 FCB $24 ; DPR
"00100101", "00100110", -- F81C - 2526 FDB $2526 ; IX
"00100111", "00101000", -- F81E - 2728 FDB $2728 ; IY
"00101001", "00101010", -- F820 - 292A FDB $292A ; UP
"11111000", "00001001", -- F822 - F809 FDB SWI3VEC ; PC
"10010001", -- F824 - 91 STACK1 FCB $91 ; CC
"00010010", -- F825 - 12 FCB $12 ; ACCA
"00010011", -- F826 - 13 FCB $13 ; ACCB
"00010100", -- F827 - 14 FCB $14 ; DPR
"00010101", "00010110", -- F828 - 1516 FDB $1516 ; IX
"00010111", "00011000", -- F82A - 1718 FDB $1718 ; IY
"00011001", "00011010", -- F82C - 191A FDB $191A ; UP
"11111000", "00000000", -- F82E - F800 FDB RESET ; PC
-- F830 STACK EQU *
--
-- Interrupt Cectors Start Here
--
"11111000", "00000000", -- F830 - F800 FDB RESET ; RESV
"11111000", "00001001", -- F832 - F809 FDB SWIVEC3 ; SWI3
"11111000", "00000111", -- F834 - F807 FDB SWIVEC2 ; SWI2
"11111000", "00000000", -- F836 - F800 fdb RESET ; FIRQ
"11111000", "00000000", -- F838 - F800 fdb RESET ; IRQ
"11111000", "00000101", -- F83A - F805 fdb SWIVEC ; SWI
"11111000", "00000000", -- F83C - F800 fcb RESET ; NMI
"11111000", "00000000" -- F83E - F800 fdb RESET ; Reset
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(5 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/trunk/rtl/vhdl/trap.vhd
0,0 → 1,288
--===========================================================================--
--
-- S Y N T H E Z I A B L E Timer C O R E
--
-- www.OpenCores.Org - May 2003
-- This core adheres to the GNU public license
--
-- File name : Trap.vhd
--
-- entity name : trap
--
-- Purpose : Implements a 8 bit address and data comparitor module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Author : John E. Kent
--
--===========================================================================----
--
-- Revision History:
--
-- Date: Revision Author
-- 5 May 2003 0.1 John Kent
--
--===========================================================================----
--
-- Register Memory Map
--
-- $00 - Address Comparitor High Byte
-- $01 - Address Comparitor Low byte
-- $02 - Data Comparitor
-- $03 - Control Comparitor
-- $04 - Address Qualifier High Byte
-- $05 - Address Qualifier Low byte
-- $06 - Data Qualifier
-- $07 - Control Qualifier
--
-- Address, Data and Control signals must match in the Comparitor registers
-- Matches are qualified by setting a bit in the Qualifier registers
--
-- Control Comparitor / Qualify (write)
-- b0 - r/w 1=read 0=write
-- b1 - vma 1=valid 0=invalid
-- b7 - irq output 1=match 0=mismatch
--
-- Control Qualifier Read
-- b7 - match flag
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity trap is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
vma : in std_logic;
addr : in std_logic_vector(15 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic
);
end;
 
architecture trap_arch of trap is
 
--
-- Trap registers
--
signal comp_addr_hi : std_logic_vector(7 downto 0);
signal comp_addr_lo : std_logic_vector(7 downto 0);
signal qual_addr_hi : std_logic_vector(7 downto 0);
signal qual_addr_lo : std_logic_vector(7 downto 0);
signal comp_data : std_logic_vector(7 downto 0);
signal qual_data : std_logic_vector(7 downto 0);
signal comp_ctrl : std_logic_vector(7 downto 0);
signal qual_ctrl : std_logic_vector(7 downto 0);
signal match_flag : std_logic;
begin
 
 
--------------------------------
--
-- write control registers
--
--------------------------------
trap_write : process( clk, rst, cs, rw, addr, data_in,
comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl )
begin
if clk'event and clk = '0' then
if rst = '1' then
comp_addr_hi <= "00000000";
comp_addr_lo <= "00000000";
comp_data <= "00000000";
comp_ctrl <= "00000000";
qual_addr_hi <= "00000000";
qual_addr_lo <= "00000000";
qual_data <= "00000000";
qual_ctrl <= "00000000";
elsif cs = '1' and rw = '0' then
case addr(2 downto 0) is
when "000" =>
comp_addr_hi <= data_in;
comp_addr_lo <= comp_addr_lo;
comp_data <= comp_data;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= qual_addr_lo;
qual_data <= qual_data;
qual_ctrl <= qual_ctrl;
when "001" =>
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= data_in;
comp_data <= comp_data;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= qual_addr_lo;
qual_data <= qual_data;
qual_ctrl <= qual_ctrl;
when "010" =>
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= comp_addr_lo;
comp_data <= data_in;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= qual_addr_lo;
qual_data <= qual_data;
qual_ctrl <= qual_ctrl;
when "011" =>
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= comp_addr_lo;
comp_data <= comp_data;
comp_ctrl <= data_in;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= qual_addr_lo;
qual_data <= qual_data;
qual_ctrl <= qual_ctrl;
when "100" =>
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= comp_addr_lo;
comp_data <= comp_data;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= data_in;
qual_addr_lo <= qual_addr_lo;
qual_data <= qual_data;
qual_ctrl <= qual_ctrl;
when "101" =>
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= comp_addr_lo;
comp_data <= comp_data;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= data_in;
qual_data <= qual_data;
qual_ctrl <= qual_ctrl;
when "110" =>
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= comp_addr_lo;
comp_data <= comp_data;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= qual_addr_lo;
qual_data <= data_in;
qual_ctrl <= qual_ctrl;
-- when "111" =>
when others =>
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= comp_addr_lo;
comp_data <= comp_data;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= qual_addr_lo;
qual_data <= qual_data;
qual_ctrl <= data_in;
end case;
else
comp_addr_hi <= comp_addr_hi;
comp_addr_lo <= comp_addr_lo;
comp_data <= comp_data;
comp_ctrl <= comp_ctrl;
qual_addr_hi <= qual_addr_hi;
qual_addr_lo <= qual_addr_lo;
qual_data <= qual_data;
qual_ctrl <= qual_ctrl;
end if;
end if;
end process;
 
--
-- trap data output mux
--
trap_read : process( addr,
comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl,
match_flag )
begin
case addr(2 downto 0) is
when "000" =>
data_out <= comp_addr_hi;
when "001" =>
data_out <= comp_addr_lo;
when "010" =>
data_out <= comp_data;
when "011" =>
data_out <= comp_ctrl;
when "100" =>
data_out <= qual_addr_hi;
when "101" =>
data_out <= qual_addr_lo;
when "110" =>
data_out <= qual_data;
-- when "111" =>
when others =>
data_out(6 downto 0) <= qual_ctrl(6 downto 0);
data_out(7) <= match_flag;
end case;
end process;
 
 
--
-- Trap hardware
--
trap_match : process( Clk, rst, cs, rw, addr, vma, match_flag, data_in,
comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl)
variable match : std_logic;
variable match_addr_hi : std_logic;
variable match_addr_lo : std_logic;
variable match_data : std_logic;
variable match_ctrl : std_logic;
 
begin
match_addr_hi :=
((comp_addr_hi(7) xor addr(15) ) and qual_addr_hi(7) ) or
((comp_addr_hi(6) xor addr(14) ) and qual_addr_hi(6) ) or
((comp_addr_hi(5) xor addr(13) ) and qual_addr_hi(5) ) or
((comp_addr_hi(4) xor addr(12) ) and qual_addr_hi(4) ) or
((comp_addr_hi(3) xor addr(11) ) and qual_addr_hi(3) ) or
((comp_addr_hi(2) xor addr(10) ) and qual_addr_hi(2) ) or
((comp_addr_hi(1) xor addr( 9) ) and qual_addr_hi(1) ) or
((comp_addr_hi(0) xor addr( 8) ) and qual_addr_hi(0) );
match_addr_lo :=
((comp_addr_lo(7) xor addr( 7) ) and qual_addr_lo(7) ) or
((comp_addr_lo(6) xor addr( 6) ) and qual_addr_lo(6) ) or
((comp_addr_lo(5) xor addr( 5) ) and qual_addr_lo(5) ) or
((comp_addr_lo(4) xor addr( 4) ) and qual_addr_lo(4) ) or
((comp_addr_lo(3) xor addr( 3) ) and qual_addr_lo(3) ) or
((comp_addr_lo(2) xor addr( 2) ) and qual_addr_lo(2) ) or
((comp_addr_lo(1) xor addr( 1) ) and qual_addr_lo(1) ) or
((comp_addr_lo(0) xor addr( 0) ) and qual_addr_lo(0) );
match_data :=
((comp_data(7) xor data_in(7)) and qual_data(7) ) or
((comp_data(6) xor data_in(6)) and qual_data(6) ) or
((comp_data(5) xor data_in(5)) and qual_data(5) ) or
((comp_data(4) xor data_in(4)) and qual_data(4) ) or
((comp_data(3) xor data_in(3)) and qual_data(3) ) or
((comp_data(2) xor data_in(2)) and qual_data(2) ) or
((comp_data(1) xor data_in(1)) and qual_data(1) ) or
((comp_data(0) xor data_in(0)) and qual_data(0) );
match_ctrl :=
((comp_ctrl(0) xor rw ) and qual_ctrl(0) ) or
((comp_ctrl(1) xor vma ) and qual_ctrl(1) );
 
match := not ( match_addr_hi or match_addr_lo or match_data or match_ctrl);
 
if clk'event and clk = '0' then
if rst = '1' then
match_flag <= '0';
elsif cs = '1' and rw = '0' then
match_flag <= '0';
else
if match = comp_ctrl(7) then
match_flag <= '1';
else
match_flag <= match_flag;
end if;
 
end if;
end if;
irq <= match_flag and qual_ctrl(7);
end process;
 
end trap_arch;
/trunk/rtl/vhdl/miniUART3.vhd
0,0 → 1,394
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : miniuart2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 1.0 Ovidiu Lupas January 2000 Synthesis optimizations
-- 2.0 Ovidiu Lupas April 2000 Bugs removed - RSBusCtrl
-- the RSBusCtrl did not process all possible situations
--
-- olupas@opencores.org
--
-- 3.0 John Kent October 2002 Changed Status bits to match mc6805
-- Added CTS, RTS, Baud rate control
-- & Software Reset
-- 3.1 John Kent 5 January 2003 Added Word Format control a'la mc6850
-- 3.2 John Kent 19 July 2003 Latched Data input to UART
-- 3.3 John Kent 16 January 2004 Integrated clkunit in rxunit & txunit
-- Now has external TX 7 RX Baud Clock
-- inputs like the MC6850...
-- also supports x1 clock and DCD.
--
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Entity for miniUART Unit - 9600 baudrate --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity miniUART is
port (
--
-- CPU signals
--
clk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic; -- miniUART Chip Select
rw : in Std_Logic; -- Read / Not Write
irq : out Std_Logic; -- Interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In
DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
--
-- Uart Signals
--
RxC : in Std_Logic; -- Receive Baud Clock
TxC : in Std_Logic; -- Transmit Baud Clock
RxD : in Std_Logic; -- Receive Data
TxD : out Std_Logic; -- Transmit Data
DCD_n : in Std_Logic; -- Data Carrier Detect
CTS_n : in Std_Logic; -- Clear To Send
RTS_n : out Std_Logic ); -- Request To send
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for miniUART Controller Unit
-------------------------------------------------------------------------------
architecture uart of miniUART is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxData : Std_Logic_Vector(7 downto 0); --
signal TxData : Std_Logic_Vector(7 downto 0); --
signal StatReg : Std_Logic_Vector(7 downto 0); -- status register
-- StatReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- Irq | PErr | ORErr | FErr | CTS | DCD | TBufE | DRdy |
-----------+--------+--------+--------+--------+--------+--------+--------+
signal CtrlReg : Std_Logic_Vector(7 downto 0); -- control register
-- CtrlReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- RxIEnb |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)|
-----------+--------+--------+--------+--------+--------+--------+--------+
-- RxIEnb
-- 0 - Rx Interrupt disabled
-- 1 - Rx Interrupt enabled
-- TxCtl
-- 0 1 - Tx Interrupt Enable
-- 1 0 - RTS high
-- WdFmt
-- 0 0 0 - 7 data, even parity, 2 stop
-- 0 0 1 - 7 data, odd parity, 2 stop
-- 0 1 0 - 7 data, even parity, 1 stop
-- 0 1 1 - 7 data, odd parity, 1 stop
-- 1 0 0 - 8 data, no parity, 2 stop
-- 1 0 1 - 8 data, no parity, 1 stop
-- 1 1 0 - 8 data, even parity, 1 stop
-- 1 1 1 - 8 data, odd parity, 1 stop
-- BdCtl
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
signal TxDbit : Std_Logic; -- Transmit data bit
signal DRdy : Std_Logic; -- Receive Data ready
signal TBufE : Std_Logic; -- Transmit buffer empty
signal FErr : Std_Logic; -- Frame error
signal OErr : Std_Logic; -- Output error
signal PErr : Std_Logic; -- Parity Error
signal TxIEnb : Std_Logic; -- Transmit interrupt enable
signal Read : Std_Logic; -- Read receive buffer
signal Load : Std_Logic; -- Load transmit buffer
signal ReadCS : Std_Logic; -- Read Status register
signal LoadCS : Std_Logic; -- Load Control register
signal Reset : Std_Logic; -- Reset (Software & Hardware)
signal RxRst : Std_Logic; -- Receive Reset (Software & Hardware)
signal TxRst : Std_Logic; -- Transmit Reset (Software & Hardware)
signal DCDDel : Std_Logic; -- Delayed DCD_n
signal DCDEdge : Std_Logic; -- Rising DCD_N Edge Pulse
signal DCDState : Std_Logic; -- DCD Reset sequencer
signal DCDInt : Std_Logic; -- DCD Interrupt
 
-----------------------------------------------------------------------------
-- Receive Unit
-----------------------------------------------------------------------------
component RxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
ReadD : in Std_Logic; -- Read data signal
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
RxClk : in Std_Logic; -- RS-232 clock input
RxDat : in Std_Logic; -- RS-232 data input
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0));
end component;
-----------------------------------------------------------------------------
-- Transmitter Unit
-----------------------------------------------------------------------------
component TxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
LoadD : in Std_Logic; -- Load transmit data
DAIn : in Std_Logic_Vector(7 downto 0);
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
TxClk : in Std_Logic; -- Enable input
TxDat : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic ); -- Tx buffer empty
end component;
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
RxDev : RxUnit port map (
Clk => clk,
Reset => RxRst,
ReadD => Read,
WdFmt => CtrlReg(4 downto 2),
BdFmt => CtrlReg(1 downto 0),
RxClk => RxC,
RxDat => RxD,
FRErr => FErr,
ORErr => OErr,
PAErr => PErr,
DARdy => DRdy,
DAOut => RxData
);
 
TxDev : TxUnit port map (
Clk => clk,
Reset => TxRst,
LoadD => Load,
DAIn => TxData,
WdFmt => CtrlReg(4 downto 2),
BdFmt => CtrlReg(1 downto 0),
TxClk => TxC,
TxDat => TxDbit,
TBE => TBufE
);
 
-----------------------------------------------------------------------------
-- Implements the controller for Rx&Tx units
-----------------------------------------------------------------------------
miniUart_Status : process(clk, Reset, CtrlReg, TxIEnb,
DRdy, TBufE, DCD_n, CTS_n, DCDInt,
FErr, OErr, PErr )
variable Int : Std_Logic;
begin
if Reset = '1' then
Int := '0';
StatReg <= "00000000";
irq <= '0';
elsif clk'event and clk='0' then
Int := (CtrlReg(7) and DRdy) or
(CtrlReg(7) and DCDInt) or
(TxIEnb and TBufE);
StatReg(0) <= DRdy; -- Receive Data Ready
StatReg(1) <= TBufE and (not CTS_n); -- Transmit Buffer Empty
StatReg(2) <= DCDInt; -- Data Carrier Detect
StatReg(3) <= CTS_n; -- Clear To Send
StatReg(4) <= FErr; -- Framing error
StatReg(5) <= OErr; -- Overrun error
StatReg(6) <= PErr; -- Parity error
StatReg(7) <= Int;
irq <= Int;
end if;
end process;
 
 
-----------------------------------------------------------------------------
-- Transmit control
-----------------------------------------------------------------------------
 
miniUart_TxControl : process( CtrlReg, TxDbit )
begin
case CtrlReg(6 downto 5) is
when "00" => -- Disable TX Interrupts, Assert RTS
RTS_n <= '0';
TxIEnb <= '0';
TxD <= TxDbit;
when "01" => -- Enable TX interrupts, Assert RTS
RTS_n <= '0';
TxIEnb <= '1';
TxD <= TxDbit;
when "10" => -- Disable Tx Interrupts, Clear RTS
RTS_n <= '1';
TxIEnb <= '0';
TxD <= TxDbit;
when "11" => -- Disable Tx interrupts, Assert RTS, send break
RTS_n <= '0';
TxIEnb <= '0';
TxD <= '0';
when others =>
RTS_n <= '0';
TxIEnb <= '0';
TxD <= TxDbit;
end case;
end process;
 
-----------------------------------------------------------------------------
-- Write to control register
-----------------------------------------------------------------------------
 
miniUart_Control: process(clk, Reset, cs, rw, Addr, DataIn, CtrlReg, TxData )
begin
if (reset = '1') then
TxData <= "00000000";
Load <= '0';
Read <= '0';
CtrlReg <= "00000000";
LoadCS <= '0';
ReadCS <= '0';
elsif clk'event and clk='0' then
if cs = '1' then
if Addr = '1' then -- Data Register
if rw = '0' then -- write data register
TxData <= DataIn;
Load <= '1';
Read <= '0';
else -- read Data Register
TxData <= TxData;
Load <= '0';
Read <= '1';
end if; -- rw
CtrlReg <= CtrlReg;
LoadCS <= '0';
ReadCS <= '0';
else -- Control / Status register
TxData <= TxData;
Load <= '0';
Read <= '0';
if rw = '0' then -- write control register
CtrlReg <= DataIn;
LoadCS <= '1';
ReadCS <= '0';
else -- read status Register
CtrlReg <= CtrlReg;
LoadCS <= '0';
ReadCS <= '1';
end if; -- rw
end if; -- Addr
else -- not selected
TxData <= TxData;
Load <= '0';
Read <= '0';
CtrlReg <= CtrlReg;
LoadCS <= '0';
ReadCS <= '0';
 
end if; -- cs
end if; -- clk / reset
end process;
 
---------------------------------------------------------------
--
-- set data output mux
--
--------------------------------------------------------------
 
miniUart_data_read: process(Addr, StatReg, RxData)
begin
if Addr = '1' then
DataOut <= RxData; -- read data register
else
DataOut <= StatReg; -- read status register
end if; -- Addr
end process;
 
 
---------------------------------------------------------------
--
-- Data Carrier Detect Edge rising edge detect
--
---------------------------------------------------------------
miniUart_DCD_edge : process( reset, clk, DCD_n, DCDDel )
begin
if reset = '1' then
DCDEdge <= '0';
DCDDel <= '0';
elsif clk'event and clk = '0' then
DCDDel <= DCD_n;
DCDEdge <= DCD_n and (not DCDDel);
end if;
end process;
 
 
---------------------------------------------------------------
--
-- Data Carrier Detect Interrupt
--
---------------------------------------------------------------
miniUart_DCD_int : process( reset, clk, DCDEdge, DCDState, Read, ReadCS, DCDInt )
begin
if reset = '1' then
DCDInt <= '0';
DCDState <= '0';
elsif clk'event and clk = '0' then
if DCDEdge = '1' then
DCDInt <= '1';
DCDState <= '0';
elsif DCDState = '0' then
-- To reset DCD interrupt, First read status
if (ReadCS <= '1') and (DCDInt = '1') then
DCDState <= '1';
else
DCDState <= '0';
end if;
DCDInt <= DCDInt;
else -- DCDstate = '1'
-- Then read the data register
if Read <= '1' then
DCDState <= '0';
DCDInt <= '0';
else
DCDState <= DCDState;
DCDInt <= DCDInt;
end if;
end if; -- DCDState
end if; -- clk / reset
end process;
 
---------------------------------------------------------------
--
-- reset may be hardware or software
--
---------------------------------------------------------------
 
miniUart_reset: process(rst, CtrlReg, Reset, DCD_n )
begin
Reset <= (CtrlReg(1) and CtrlReg(0)) or rst;
TxRst <= Reset;
RxRst <= Reset or DCD_n;
end process;
 
end; --===================== End of architecture =======================--
 
/trunk/rtl/vhdl/rxunit3.vhd
0,0 → 1,396
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : rxunit3.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the cpu68 cpu and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164.all;
-- ieee.numeric_std.all;
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 Added 6850 word format control
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code.
-- 3.2 John Kent 10 January 2004 Rewrite of code.
-- dilbert57@opencores.org
-------------------------------------------------------------------------------
-- Description : Implements the receive unit of the miniUART core. Samples
-- 16 times the RxD line and retain the value in the middle of
-- the time interval.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Receive unit
-------------------------------------------------------------------------------
entity RxUnit is
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
ReadD : in Std_Logic; -- Read data signal
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
RxClk : in Std_Logic; -- RS-232 clock input
RxDat : in Std_Logic; -- RS-232 data input
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0)
);
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for receive Unit
-------------------------------------------------------------------------------
architecture Behaviour of RxUnit is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxDebDel0 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDebDel1 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDebDel2 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDebDel3 : Std_Logic; -- Debounce Delayed Rx Data
signal RxDeb : Std_Logic; -- Debounced Rx Data
signal RxDatDel : Std_Logic; -- Delayed Rx Data
signal RxDatEdge : Std_Logic; -- Rx Data Edge pulse
signal RxClkDel : Std_Logic; -- Delayed Rx Input Clock
signal RxClkEdge : Std_Logic; -- Rx Input Clock Edge pulse
signal RxClkCnt : Std_Logic_Vector(5 downto 0); -- Rx Baud Clock Counter
signal RxBdClk : Std_Logic; -- Rx Baud Clock
signal RxBdDel : Std_Logic; -- Delayed Rx Baud Clock
signal RxBdEdge : Std_Logic; -- Rx Baud Clock Edge pulse
signal RxStart : Std_Logic; -- Rx Start bit detected
 
signal tmpDRdy : Std_Logic; -- Data Ready flag
signal RxValid : Std_Logic; -- Rx Data Valid
signal tmpRxVal : Std_Logic; -- Rx Data Valid
signal outErr : Std_Logic; -- Over run error bit
signal frameErr : Std_Logic; -- Framing error bit
signal ParityErr : Std_Logic; -- Parity Error Bit
signal RxParity : Std_Logic; -- Calculated RX parity bit
signal RxState : Std_Logic_Vector(3 downto 0); -- receive bit state
signal ShtReg : Std_Logic_Vector(7 downto 0); -- Shift Register
signal DataOut : Std_Logic_Vector(7 downto 0); -- Data Output register
 
begin
 
---------------------------------------------------------------------
-- Receiver Data Debounce
-- Input level must be stable for 4 Receive Clock cycles.
---------------------------------------------------------------------
rxunit_data_debounce : process(Clk, Reset, RxClkEdge, RxDat,
RxDebDel0, RxDebDel1, RxDebDel2, RxDebDel3 )
begin
if Reset = '1' then
RxDebDel0 <= RxDat;
RxDebDel1 <= RxDat;
RxDebDel2 <= RxDat;
RxDebDel3 <= RxDat;
elsif Clk'event and Clk = '0' then
if RxClkEdge = '1' then
RxDebDel0 <= RxDat;
RxDebDel1 <= RxDebDel0;
RxDebDel2 <= RxDebDel1;
RxDebDel3 <= RxDebDel2;
if (RxDebDel3 or RxDebDel2 or RxDebDel1 or RxDebDel0) = '0' then
RxDeb <= '0';
elsif (RxDebDel3 and RxDebDel2 and RxDebDel1 and RxDebDel0) = '1' then
RxDeb <= '1';
else
RxDeb <= RxDeb;
end if;
else
RxDebDel0 <= RxDebDel0;
RxDebDel1 <= RxDebDel1;
RxDebDel2 <= RxDebDel2;
RxDebDel3 <= RxDebDel3;
RxDeb <= RxDeb;
end if;
end if;
end process;
 
---------------------------------------------------------------------
-- Receiver Data Edge Detection
-- A falling edge will produce a one clock cycle pulse
---------------------------------------------------------------------
rxunit_data_edge : process(Clk, Reset, RxDeb, RxDatDel )
begin
if Reset = '1' then
RxDatDel <= RxDeb;
RxDatEdge <= '0';
elsif Clk'event and Clk = '0' then
RxDatDel <= RxDeb;
RxDatEdge <= RxDatDel and (not RxDeb);
end if;
end process;
 
---------------------------------------------------------------------
-- Receiver Clock Edge Detection
-- A rising edge will produce a one clock cycle pulse
-- RxClock
---------------------------------------------------------------------
rxunit_clock_edge : process(Clk, Reset, RxClk, RxClkDel )
begin
if Reset = '1' then
RxClkDel <= RxClk;
RxClkEdge <= '0';
elsif Clk'event and Clk = '0' then
RxClkDel <= RxClk;
RxClkEdge <= RxClk and (not RxClkDel);
end if;
end process;
 
 
---------------------------------------------------------------------
-- Receiver Clock Divider
-- Reset the Rx Clock divider on any data edge
-- Note that debounce data will be skewed by 4 clock cycles.
-- Advance the count only on an input clock pulse
---------------------------------------------------------------------
rxunit_clock_divide : process(Clk, Reset, RxDatEdge, RxState, RxStart,
RxClkEdge, RxClkCnt )
begin
if Reset = '1' then
RxClkCnt <= "000000";
RxStart <= '0';
elsif Clk'event and Clk = '0' then
 
if RxState = "1111" then -- idle state
if RxStart = '0' then -- in hunt mode
if RxDatEdge = '1' then -- falling edge starts counter
RxStart <= '1';
else
RxStart <= RxStart; -- other wise remain halted
end if;
else
RxStart <= RxStart; -- Acquired start, stay in this state
end if;
else
RxStart <= '0'; -- non idle, reset start flag
end if; -- RxState
 
if RxState = "1111" and RxStart = '0' then
RxClkCnt <= "000011"; -- Reset to 3 to account for debounce skew
else
if RxClkEdge = '1' then
RxClkCnt <= RxClkCnt + "000001";
else
RxClkCnt <= RxClkCnt;
end if; -- RxClkEdge
end if; -- RxState
end if; -- clk / reset
end process;
 
---------------------------------------------------------------------
-- Receiver Clock Selector
-- Select output then look for rising edge
---------------------------------------------------------------------
rxunit_clock_select : process(Clk, Reset, BdFmt, RxClk, RxClkCnt,
RxBdDel, RxBdEdge )
begin
-- BdFmt
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
case BdFmt is
when "00" => -- Div by 1
RxBdClk <= RxClk;
when "01" => -- Div by 16
RxBdClk <= RxClkCnt(3);
when "10" => -- Div by 64
RxBdClk <= RxClkCnt(5);
when others => -- reset
RxBdClk <= '0';
end case;
 
if Reset = '1' then
RxBdDel <= RxBdClk;
RxBdEdge <= '0';
elsif Clk'event and Clk = '0' then
RxBdDel <= RxBdClk;
RxBdEdge <= RxBdClk and (not RxBdDel);
end if;
 
end process;
 
 
---------------------------------------------------------------------
-- Receiver process
---------------------------------------------------------------------
rxunit_receive : process(Clk, Reset, RxState, RxBdEdge, RxDat )
begin
if Reset = '1' then
frameErr <= '0';
outErr <= '0';
parityErr <= '0';
 
ShtReg <= "00000000"; -- Shift register
DataOut <= "00000000";
RxParity <= '0'; -- Parity bit
RxValid <= '0'; -- Data RX data valid flag
RxState <= "1111";
elsif Clk'event and Clk='0' then
if RxBdEdge = '1' then
case RxState is
when "0000" | "0001" | "0010" | "0011" |
"0100" | "0101" | "0110" => -- data bits 0 to 6
ShtReg <= RxDat & ShtReg(7 downto 1);
RxParity <= RxParity xor RxDat;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if RxState = "0110" then
if WdFmt(2) = '0' then
RxState <= "1000"; -- 7 data + parity
else
RxState <= "0111"; -- 8 data bits
end if; -- WdFmt(2)
else
RxState <= RxState + "0001";
end if; -- RxState
 
when "0111" => -- data bit 7
ShtReg <= RxDat & ShtReg(7 downto 1);
RxParity <= RxParity xor RxDat;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if WdFmt(1) = '1' then -- parity bit ?
RxState <= "1000"; -- yes, go to parity
else
RxState <= "1001"; -- no, must be 2 stop bit bits
end if;
 
when "1000" => -- parity bit
if WdFmt(2) = '0' then
ShtReg <= RxDat & ShtReg(7 downto 1); -- 7 data + parity
else
ShtReg <= ShtReg; -- 8 data + parity
end if;
RxParity <= RxParity;
if WdFmt(0) = '0' then -- parity polarity ?
if RxParity = RxDat then -- check even parity
parityErr <= '1';
else
parityErr <= '0';
end if;
else
if RxParity = RxDat then -- check for odd parity
parityErr <= '0';
else
parityErr <= '1';
end if;
end if;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxState <= "1001";
 
when "1001" => -- stop bit (Only one required for RX)
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
if RxDat = '1' then -- stop bit expected
frameErr <= '0'; -- yes, no framing error
else
frameErr <= '1'; -- no, framing error
end if;
if tmpDRdy = '1' then -- Has previous data been read ?
outErr <= '1'; -- no, overrun error
else
outErr <= '0'; -- yes, no over run error
end if;
RxValid <= '1';
DataOut <= ShtReg;
RxState <= "1111";
 
when others => -- this is the idle state
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if RxDat = '0' then -- look for start request
RxState <= "0000"; -- yes, read data
else
RxState <= "1111"; -- otherwise idle
end if;
end case; -- RxState
else -- RxBdEdge
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= RxValid;
DataOut <= DataOut;
RxState <= RxState;
end if; -- RxBdEdge
end if; -- clk / reset
end process;
 
 
---------------------------------------------------------------------
-- Receiver Read process
---------------------------------------------------------------------
rxunit_read : process(Clk, Reset, ReadD, RxValid, tmpRxVal, tmpDRdy )
begin
if Reset = '1' then
tmpDRdy <= '0';
tmpRxVal <= '0';
elsif Clk'event and Clk='0' then
if ReadD = '1' then
-- Data was read, reset data ready
tmpDRdy <= '0';
tmpRxVal <= tmpRxVal;
else
if RxValid = '1' and tmpRxVal = '0' then
-- Data was received, set Data ready
tmpDRdy <= '1';
tmpRxVal <= '1';
else
-- Test for falling edge of RxValid.
tmpDRdy <= tmpDRdy;
if RxValid = '0' and tmpRxVal = '1' then
tmpRxVal <= '0';
else
tmpRxVal <= tmpRxVal;
end if;
end if; -- RxValid
end if; -- ReadD
end if; -- clk / reset
end process;
 
 
DARdy <= tmpDRdy;
DAOut <= DataOut;
FRErr <= frameErr;
ORErr <= outErr;
PAErr <= parityErr;
 
end Behaviour; --==================== End of architecture ====================--
/trunk/rtl/vhdl/ram2k.vhd
0,0 → 1,214
--
-- Ram2k.vhd
--
-- 2K Byte RAM made out of 4 x 512 byte Block RAMs.
-- John Kent
-- 11 February 2004
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library unisim;
use unisim.all;
 
entity ram_2k is
Port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector (10 downto 0);
wdata : in std_logic_vector (7 downto 0);
rdata : out std_logic_vector (7 downto 0)
);
end ram_2k;
 
architecture rtl of ram_2k is
 
signal we : std_logic;
signal reset : std_logic;
signal rdata0 : std_logic_vector (7 downto 0);
signal rdata1 : std_logic_vector (7 downto 0);
signal rdata2 : std_logic_vector (7 downto 0);
signal rdata3 : std_logic_vector (7 downto 0);
signal ena0 : std_logic;
signal ena1 : std_logic;
signal ena2 : std_logic;
signal ena3 : std_logic;
 
component RAMB4_S8
generic (
INIT_00, INIT_01, INIT_02, INIT_03,
INIT_04, INIT_05, INIT_06, INIT_07,
INIT_08, INIT_09, INIT_0A, INIT_0B,
INIT_0C, INIT_0D, INIT_0E, INIT_0F : bit_vector (255 downto 0) :=
x"0000000000000000000000000000000000000000000000000000000000000000"
);
 
port (
clk, we, en, rst : in std_logic;
addr : in std_logic_vector(8 downto 0);
di : in std_logic_vector(7 downto 0);
do : out std_logic_vector(7 downto 0)
);
end component;
 
begin
 
MY_RAM0 : RAMB4_S8
generic map (
INIT_00 => x"000000FF0000001010101010101010003E1C7F7F3E1C08000000FF0000000000",
INIT_01 => x"202020202020200000FF0000000000000000000000FF000000000000FF000000",
INIT_02 => x"0000E0100808080000000304080808080810E000000000040404040404040420",
INIT_03 => x"808080808080FF80402010080402010102040810204080FF8080808080808000",
INIT_04 => x"081C3E7F7F7F3600FF000000000000003C7E7E7E7E3C0001010101010101FF80",
INIT_05 => x"3C424242423C0081422418182442810808040300000000404040404040404000",
INIT_06 => x"0808FF0808080800081C3E7F3E1C0802020202020202020008082A772A1C0800",
INIT_07 => x"03070F1F3F7FFF001414543E010000080808080808080850A050A050A050A008",
INIT_08 => x"24247E247E242400000000002424240008000008080808000000000000000000",
INIT_09 => x"00000000100804003A444A30484830004626100864620000083C0A1C281E0800",
INIT_0A => x"0008083E08080000082A1C3E1C2A080020100808081020000408101010080400",
INIT_0B => x"402010080402000018180000000000000000007E000000100808000000000000",
INIT_0C => x"3C42021C02423C007E40300C02423C003E080808281808003C42625A46423C00",
INIT_0D => x"1010100804427E003C42427C40201C003844020478407E0004047E24140C0400",
INIT_0E => x"080800000800000000080000080000003804023E42423C003C42423C42423C00",
INIT_0F => x"1000100C02423C0070180C060C18700000007E007E0000000E18306030180E10"
)
 
port map ( clk => clk,
en => ena0,
we => we,
rst => reset,
addr(8 downto 0) => addr(8 downto 0),
di(7 downto 0) => wdata(7 downto 0),
do(7 downto 0) => rdata0(7 downto 0)
);
 
MY_RAM1 : RAMB4_S8
generic map (
 
INIT_00 => x"001C22404040221C007C22223C22227C004242427E422418001E204C564A221C",
INIT_01 => x"001C22424E40221C004040407840407E007E40407840407E0078242222222478",
INIT_02 => x"0042444870484442003844040404040E001C08080808081C004242427E424242",
INIT_03 => x"0018244242422418004242464A526242004242425A5A6642007E404040404040",
INIT_04 => x"003C42023C40423C004244487C42427C001A244A42422418004040407C42427C",
INIT_05 => x"0042665A5A4242420018182424424242003C424242424242000808080808083E",
INIT_06 => x"003C20202020203C007E40201804027E000808081C2222220042422418244242",
INIT_07 => x"0010207F20100000080808082A1C0800003C04040404043C006E70103C10100C",
INIT_08 => x"003C4240423C0000005C6242625C4040003A443C04380000001E204C564A221C",
INIT_09 => x"3C023A46463A0000001010107C10120C003C407E423C0000003A4642463A0202",
INIT_0A => x"004468504844404038440404040C0004001C08080818000800424242625C4040",
INIT_0B => x"003C4242423C000000424242625C00000049494949760000001C080808080818",
INIT_0C => x"007C023C403E000000404040625C000002023A46463A000040405C62625C0000",
INIT_0D => x"00364949494100000018244242420000003A464242420000000C1210107C1010",
INIT_0E => x"003C20202020203C007E2018047E00003C023A46424200000042241824420000",
INIT_0F => x"0010207F20100000080808082A1C0800003C04040404043C006E70103C10100C"
)
 
port map ( clk => clk,
en => ena1,
we => we,
rst => reset,
addr(8 downto 0) => addr(8 downto 0),
di(7 downto 0) => wdata(7 downto 0),
do(7 downto 0) => rdata1(7 downto 0)
);
 
MY_RAM2 : RAMB4_S8
generic map (
INIT_00 => x"000000FF0000001010101010101010003E1C7F7F3E1C08000000FF0000000000",
INIT_01 => x"202020202020200000FF0000000000000000000000FF000000000000FF000000",
INIT_02 => x"0000E0100808080000000304080808080810E000000000040404040404040420",
INIT_03 => x"808080808080FF80402010080402010102040810204080FF8080808080808000",
INIT_04 => x"081C3E7F7F7F3600FF000000000000003C7E7E7E7E3C0001010101010101FF80",
INIT_05 => x"3C424242423C0081422418182442810808040300000000404040404040404000",
INIT_06 => x"0808FF0808080800081C3E7F3E1C0802020202020202020008082A772A1C0800",
INIT_07 => x"03070F1F3F7FFF001414543E010000080808080808080850A050A050A050A008",
INIT_08 => x"24247E247E242400000000002424240008000008080808000000000000000000",
INIT_09 => x"00000000100804003A444A30484830004626100864620000083C0A1C281E0800",
INIT_0A => x"0008083E08080000082A1C3E1C2A080020100808081020000408101010080400",
INIT_0B => x"402010080402000018180000000000000000007E000000100808000000000000",
INIT_0C => x"3C42021C02423C007E40300C02423C003E080808281808003C42625A46423C00",
INIT_0D => x"1010100804427E003C42427C40201C003844020478407E0004047E24140C0400",
INIT_0E => x"080800000800000000080000080000003804023E42423C003C42423C42423C00",
INIT_0F => x"1000100C02423C0070180C060C18700000007E007E0000000E18306030180E10"
)
 
port map ( clk => clk,
en => ena2,
we => we,
rst => reset,
addr(8 downto 0) => addr(8 downto 0),
di(7 downto 0) => wdata(7 downto 0),
do(7 downto 0) => rdata2(7 downto 0)
);
 
MY_RAM3 : RAMB4_S8
generic map (
 
INIT_00 => x"001C22404040221C007C22223C22227C004242427E422418001E204C564A221C",
INIT_01 => x"001C22424E40221C004040407840407E007E40407840407E0078242222222478",
INIT_02 => x"0042444870484442003844040404040E001C08080808081C004242427E424242",
INIT_03 => x"0018244242422418004242464A526242004242425A5A6642007E404040404040",
INIT_04 => x"003C42023C40423C004244487C42427C001A244A42422418004040407C42427C",
INIT_05 => x"0042665A5A4242420018182424424242003C424242424242000808080808083E",
INIT_06 => x"003C20202020203C007E40201804027E000808081C2222220042422418244242",
INIT_07 => x"0010207F20100000080808082A1C0800003C04040404043C006E70103C10100C",
INIT_08 => x"003C4240423C0000005C6242625C4040003A443C04380000001E204C564A221C",
INIT_09 => x"3C023A46463A0000001010107C10120C003C407E423C0000003A4642463A0202",
INIT_0A => x"004468504844404038440404040C0004001C08080818000800424242625C4040",
INIT_0B => x"003C4242423C000000424242625C00000049494949760000001C080808080818",
INIT_0C => x"007C023C403E000000404040625C000002023A46463A000040405C62625C0000",
INIT_0D => x"00364949494100000018244242420000003A464242420000000C1210107C1010",
INIT_0E => x"003C20202020203C007E2018047E00003C023A46424200000042241824420000",
INIT_0F => x"0010207F20100000080808082A1C0800003C04040404043C006E70103C10100C"
)
 
port map ( clk => clk,
en => ena3,
we => we,
rst => reset,
addr(8 downto 0) => addr(8 downto 0),
di(7 downto 0) => wdata(7 downto 0),
do(7 downto 0) => rdata3(7 downto 0)
);
 
my_ram_2k : process ( clk, rst, cs, rw, rdata0, rdata1, rdata2, rdata3 )
begin
case addr(10 downto 9) is
when "00" =>
ena0 <= cs;
ena1 <= '0';
ena2 <= '0';
ena3 <= '0';
rdata <= rdata0;
when "01" =>
ena0 <= '0';
ena1 <= cs;
ena2 <= '0';
ena3 <= '0';
rdata <= rdata1;
when "10" =>
ena0 <= '0';
ena1 <= '0';
ena2 <= cs;
ena3 <= '0';
rdata <= rdata2;
when "11" =>
ena0 <= '0';
ena1 <= '0';
ena2 <= '0';
ena3 <= cs;
rdata <= rdata3;
when others =>
null;
end case;
 
we <= cs and (not rw);
reset <= rst;
 
end process;
 
end;
 
/trunk/rtl/vhdl/sbug_rom.vhd
0,0 → 1,209
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
library unisim;
use unisim.all;
 
entity sbug_rom is
Port (
MEMclk : in std_logic;
MEMaddr : in std_logic_vector (10 downto 0);
MEMrdata : out std_logic_vector (7 downto 0)
);
end sbug_rom;
 
architecture rtl of sbug_rom is
 
signal dout0 : std_logic_vector (7 downto 0);
signal dout1 : std_logic_vector (7 downto 0);
signal dout2 : std_logic_vector (7 downto 0);
signal dout3 : std_logic_vector (7 downto 0);
 
signal ena0 : std_logic;
signal ena1 : std_logic;
signal ena2 : std_logic;
signal ena3 : std_logic;
 
signal MEMwdata : std_logic_vector (7 downto 0);
 
component RAMB4_S8
generic (
INIT_00, INIT_01, INIT_02, INIT_03,
INIT_04, INIT_05, INIT_06, INIT_07,
INIT_08, INIT_09, INIT_0A, INIT_0B,
INIT_0C, INIT_0D, INIT_0E, INIT_0F : bit_vector (255 downto 0)
);
 
port (
clk, we, en, rst : in std_logic;
addr : in std_logic_vector(8 downto 0);
di : in std_logic_vector(7 downto 0);
do : out std_logic_vector(7 downto 0)
);
end component RAMB4_S8;
 
begin
 
ROM0 : RAMB4_S8
generic map (
INIT_00 => x"A780A610C6C0DF8E104FFE8E81FBADFDB1FDBDFDEEFDDFFDC9FDCFFD61F814F8",
INIT_01 => x"17431FE4A7D0866AAFDD8C30FB265AE26F0CC67A0217E0DFBF04E08EF9265AA0",
INIT_02 => x"051774FE8E260517F62A5A19048B0327856D0DC64FD0DF8E7505175FFE8EBE05",
INIT_03 => x"17408B981F7305175E86092C2081891FF1270D817F846505174605177BFE8E5C",
INIT_04 => x"201E05177DFE8EF5264FFE8C02300F2780E113FE8E20C0022F60C16705176C05",
INIT_05 => x"83FE8E310417290417210417190417110417FF041783FE8E3B341FBC2094ADC0",
INIT_06 => x"ED0317394AAF02295704171705172704174804164104173A0417330417EA0417",
INIT_07 => x"17ED0417E703173946AF02293B0417FB04170004173948AF0229490417090517",
INIT_08 => x"0229220417D10417F503173943A70229300417DF0417CE03173944AF02292D04",
INIT_09 => x"C4A7808A0429060417B50417E303173941A70229140417C30417DD03173942A7",
INIT_0A => x"03178E0417260417A4A6960417260417211F5F041783FE8E121F2D29EB031739",
INIT_0B => x"173F866F04170827A4A1A4A7390F260D8117275E81DD271881E12708811128DF",
INIT_0C => x"24E1AC203406298B031705201F30C0DF8E321F350317BE203F31C22021316C04",
INIT_0D => x"8E103439623203272704170527E4AC011FF0C4201F0634F0C41000C3101F3901",
INIT_0E => x"80A610C6E1AE100417F5265A180417B0031780A610C6AF0317E4AEE8031783FE",
INIT_0F => x"2562AC7B2930342B0317E26FE26FBF20EE265A0104172E8602237E8104252081"
)
 
port map ( clk => MEMclk,
en => ena0,
we => '0',
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout0(7 downto 0)
);
 
ROM1 : RAMB4_S8
generic map (
INIT_00 => x"A0E8E0EB023464E3201F62AE10F125E4AC10A0A7E0AB043464E3201FE8031777",
INIT_01 => x"3903175003174701171035880317A1FE8E10344C03173F3085031783FE8E3C27",
INIT_02 => x"AC101A268303173E0317A6FE8E981F6C03178FFE8E2E031764AE77031787FE8E",
INIT_03 => x"1E29B102173966328C26646C9026656C62AE100B267403178603172B86B325E4",
INIT_04 => x"173984A73F86A4AFA0A709273F8184A60F271035558DFFFF8E10341A24C0DF8C",
INIT_05 => x"8D4AAF0427268D1F304AAE431F39FB265A188D08C6E3DF8E104703163F864A03",
INIT_06 => x"A0A7A0A7A0A7FF8684A7A4A604263F8184A60A24C0DF8C21AE9AFD16E4FD1706",
INIT_07 => x"F0B714F0B7FF8624F0B7DE86393D3139F7265A0427A1ACA0A608C6E3DF8E1039",
INIT_08 => x"B68A001720F0B70986FB2B20F0B697001720F0B7D88610F07D16F0B715F0B710",
INIT_09 => x"F0BFFFFE8E00F0FD5343101F40F0B7108A528D00C08ECA261085F926018520F0",
INIT_0A => x"0A2A10F07D5F04345F528D20F0B78C8622F0B7018614F0B7FE8610F0B7FF8602",
INIT_0B => x"341F4AAF00C08E24F0F7DEC63901271C8520F0B604358A20F0265A0435F8265A",
INIT_0C => x"0F8462A65858585853A6E6E4E754545454A6E6D0DF8E104444444462A636343B",
INIT_0D => x"013000008E03C614E07F18E07D390435FD265A20C6043439363562E762EA62A7",
INIT_0E => x"B78C86298D1AE0B70186F92601C518E0F6378D18E0B70F86F6265AF92600008C",
INIT_0F => x"C08E3901272CC5F02601C518E0F680A71BE0B6052702C5092000C08E228D18E0"
)
 
port map ( clk => MEMclk,
en => ena1,
we => '0',
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout1(7 downto 0)
);
 
ROM2 : RAMB4_S8
generic map (
INIT_00 => x"3981A60117F9265381AD0117E2DF7FDD0117118639FD265A20C63B341F4AAF00",
INIT_01 => x"0434E46AE46AE4EBE0EBE0E610342129FF001726290234170117F12631813D27",
INIT_02 => x"738F01173F86B227FFC102355FEB2080A70527E46AE0EB02340C290435FD0017",
INIT_03 => x"A3E4EC7101171286E4AF0130462562AC4A293034B80017E26F8701161386E2DF",
INIT_04 => x"EBDA001762AEE70017981F03CB1A0117EBFE8E64E720C6022320008310062762",
INIT_05 => x"322F01171486C326E4AC62AFCD0017981F53F526646AD7001780A684EB63EB62",
INIT_06 => x"43A6DF0017CCFE8EA1001648AEEA0017BAFE8EAC0016311FF50017AEFE8E3965",
INIT_07 => x"AEBE0017B4FE8E80001646AEC90017C0FE8E8B001644AED40017C6FE8E9E0016",
INIT_08 => x"8EC4A6A00017DCFE8E6A2042A6AA0017D7FE8E742041A6B40017D2FE8E76204A",
INIT_09 => x"39103561A710343D29098D011F43290F8DBF00172D86121F4E29098D7320E3FE",
INIT_0A => x"393080032239811D2530816F8D39E0AB04342829078D891F484848483229118D",
INIT_0B => x"35028D0235103439021A39578003226681072561813937800322468112254181",
INIT_0C => x"25E46880A608C602345720078B022F3981308B0F840235048D44444444023402",
INIT_0D => x"8180A6318D391035058D75FE8E10340C20028D390235F1265A458D498D2D8602",
INIT_0E => x"3439103501A6FA27018584A6E0DFBE10341F207F84048D0627E2DF7D39F82604",
INIT_0F => x"39103501A70235FA27028584A6E0DFBE12342086008D3902350185E0DF9FA602"
)
port map ( clk => MEMclk,
en => ena2,
we => '0',
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout2(7 downto 0)
);
 
ROM3 : RAMB4_S8
generic map (
INIT_00 => x"1007F90431F90315F90223F90139E2DFB7FF86016D84A7118684A70386E0DFBE",
INIT_01 => x"67FC5041F94D0CFC4CA5F84796F945F4FA447BFA42EBF819F9F818DDF815CFF8",
INIT_02 => x"00FFFFFFFFB3FAA7F8A7F8A7F8A7F8B3FAA7FA58B3FB558AF953A8F852F2F951",
INIT_03 => x"414857043E040000000A0D4B04202D20382E31204755422D530000000A0D0000",
INIT_04 => x"203A524F525245204E492053544942202C042053534150202C04202D20043F54",
INIT_05 => x"043D53552020043D43502020043D50532020303132333435363704203E3D2004",
INIT_06 => x"43432020043D422020043D412020043D50442020043D58492020043D59492020",
INIT_07 => x"000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04315343565A4E4948464504203A",
INIT_08 => x"300B2784AC1084AF1084EEAA558E10A0D08E84A7F086FB264A80A70F86F0FF8E",
INIT_09 => x"2DA7D0DF8E10C0DFCE10FDFFB74444444443101F84EFD620ED26A0F08C00F089",
INIT_0A => x"1084AF10AA558E1084EE2227A0F08C00F08930FB2A4AA66F0C862FA7F0862E6F",
INIT_0B => x"2EA7D0DF8E10F186D520A5A70F88891F44444444101FD0DF8E1084EFE92684AC",
INIT_0C => x"8EF32D0C814C80E7A66F0427A6E6211F4F2CE7A66F1420F92A4A0526A6E60C86",
INIT_0D => x"9F6EC6DF9F6EC4DF9F6EC0DF9F6E62F816E2DFF753F9265A80A7A0A610C6F0FF",
INIT_0E => x"0822CEDFBC8B300F27FFFF8CCCDFBE49584F4AAF80E64AAE431FCADF9F6EC8DF",
INIT_0F => x"00FFB2FFC2FFBEFFBAFFB6FFC6FFB2FFC2DF9F6E42EE1F37F16E44AEC4EC1034"
)
port map ( clk => MEMclk,
en => ena3,
we => '0',
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout3(7 downto 0)
);
 
my_sbug : process ( MEMaddr, dout0, dout1, dout2, dout3 )
begin
case MEMaddr(10 downto 9) is
when "00" =>
ena0 <= '1';
ena1 <= '0';
ena2 <= '0';
ena3 <= '0';
when "01" =>
ena0 <= '0';
ena1 <= '1';
ena2 <= '0';
ena3 <= '0';
when "10" =>
ena0 <= '0';
ena1 <= '0';
ena2 <= '1';
ena3 <= '0';
when "11" =>
ena0 <= '0';
ena1 <= '0';
ena2 <= '0';
ena3 <= '1';
when others =>
ena0 <= '0';
ena1 <= '0';
ena2 <= '0';
ena3 <= '0';
end case;
 
case MEMaddr(10 downto 9) is
when "00" =>
MEMrdata <= dout0;
when "01" =>
MEMrdata <= dout1;
when "10" =>
MEMrdata <= dout2;
when "11" =>
MEMrdata <= dout3;
when others =>
MEMrdata <= x"00";
end case;
 
MEMwdata <= x"00";
 
end process my_sbug;
 
end architecture rtl;
 
/trunk/rtl/vhdl/miniuart_tb.vhd
0,0 → 1,197
--===========================================================================--
--
-- MiniUart3 Test Bench
--
--
-- John Kent 16th January 2004
--
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity miniuart3_testbench is
end miniuart3_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of miniuart3_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- CPU Interface signals
signal SysClk : Std_Logic;
signal uart_reset : Std_Logic;
signal uart_cs : Std_Logic;
signal uart_rw : Std_Logic;
signal uart_addr : Std_Logic;
signal uart_data_in : Std_Logic_Vector(7 downto 0);
signal uart_data_out: Std_Logic_Vector(7 downto 0);
signal uart_irq : Std_Logic;
signal rxclk : Std_Logic;
signal txclk : Std_Logic;
signal rxbit : Std_Logic;
signal txbit : Std_Logic;
signal dcd_n : Std_Logic;
signal cts_n : Std_Logic;
signal rts_n : Std_Logic;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
component miniUART
port (
--
-- CPU signals
--
clk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic; -- miniUART Chip Select
rw : in Std_Logic; -- Read / Not Write
irq : out Std_Logic; -- Interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In
DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
--
-- Uart Signals
--
RxC : in Std_Logic; -- Receive Baud Clock
TxC : in Std_Logic; -- Transmit Baud Clock
RxD : in Std_Logic; -- Receive Data
TxD : out Std_Logic; -- Transmit Data
DCD_n : in Std_Logic; -- Data Carrier Detect
CTS_n : in Std_Logic; -- Clear To Send
RTS_n : out Std_Logic ); -- Request To send
end component; --================== End of entity ==============================--
 
begin
 
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_uart : miniUART port map (
clk => SysClk,
rst => uart_reset,
cs => uart_cs,
rw => uart_rw,
Irq => uart_irq,
Addr => uart_addr,
Datain => uart_data_in,
DataOut => uart_data_out,
RxC => rxclk,
TxC => txclk,
RxD => rxbit,
TxD => txbit,
DCD_n => dcd_n,
CTS_n => cts_n,
RTS_n => rts_n
);
 
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cts_n <= '0';
dcd_n <= '0';
 
for count in 0 to 4096 loop
if (count mod 16) = 0 then
rxclk <= '1';
txclk <= '1';
elsif (count mod 16) = 8 then
rxclk <= '0';
txclk <= '0';
end if;
 
case count is
when 0 =>
uart_reset <= '1';
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '0';
uart_data_in <= "00000000";
rxbit <= '1';
when 1 =>
uart_reset <= '0';
when 3 =>
uart_cs <= '1';
uart_rw <= '0'; -- write control
uart_addr <= '0';
uart_data_in <= "00010001";
when 4 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '0';
uart_data_in <= "00000000";
when 5 =>
uart_cs <= '1';
uart_rw <= '0'; -- write data
uart_addr <= '1';
uart_data_in <= "01010101";
when 6 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '1';
uart_data_in <= "00000000";
when 256 =>
rxbit <= '0'; -- start
when 512 =>
rxbit <= '1'; -- bit 0
when 768 =>
rxbit <= '0'; -- bit 1
when 1024 =>
rxbit <= '1'; -- bit 2
when 1280 =>
rxbit <= '1'; -- bit3
when 1536 =>
rxbit <= '0'; -- bit 4
when 1792 =>
rxbit <= '0'; -- bit 5
when 2048 =>
rxbit <= '1'; -- bit 6
when 2304 =>
rxbit <= '0'; -- bit 7
when 2560 =>
rxbit <= '1'; -- stop 1
when 2816 =>
rxbit <= '1'; -- stop 2
when 3100 =>
uart_cs <= '1';
uart_rw <= '1'; -- read control
uart_addr <= '0';
when 3101 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '0';
when 3102 =>
uart_cs <= '1';
uart_rw <= '1'; -- read data
uart_addr <= '1';
when 3103 =>
uart_cs <= '0';
uart_rw <= '1';
uart_addr <= '1';
when others =>
null;
end case;
SysClk <= '1';
wait for 100 ns;
SysClk <= '0';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
end behavior; --===================== End of architecture =======================--
 
/trunk/rtl/vhdl/txunit3.vhd
0,0 → 1,302
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : txunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : IEEE.Std_Logic_1164
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 unnecessary variable removed
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 added 6850 word format control
-- 3.1 John Kent 12 January 2003 Rearranged state machine code
-- 3.2 John Kent 30 March 2003 Revamped State machine
-- 3.3 John Kent 16 January 2004 Major re-write - added baud rate gen
--
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Description :
-------------------------------------------------------------------------------
-- Entity for the Tx Unit --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Transmitter unit
-------------------------------------------------------------------------------
entity TxUnit is
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
LoadD : in Std_Logic; -- Load transmit data
DAIn : in Std_Logic_Vector(7 downto 0);
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
TxClk : in Std_Logic; -- Enable input
TxDat : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic ); -- Tx buffer empty
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for TxUnit
-------------------------------------------------------------------------------
architecture Behaviour of TxUnit is
type TxStateType is ( TxIdle_State, Start_State, Data_State, Parity_State, Stop_State );
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal TxClkDel : Std_Logic; -- Delayed Tx Input Clock
signal TxClkEdge : Std_Logic; -- Tx Input Clock Edge pulse
signal TxClkCnt : Std_Logic_Vector(5 downto 0); -- Tx Baud Clock Counter
signal TxBdDel : Std_Logic; -- Delayed Tx Baud Clock
signal TxBdEdge : Std_Logic; -- Tx Baud Clock Edge pulse
signal TxBdClk : Std_Logic; -- Tx Baud Clock
 
signal TBuff : Std_Logic_Vector(7 downto 0); -- transmit buffer
signal TBufE : Std_Logic; -- Transmit Buffer Empty
 
signal TReg : Std_Logic_Vector(7 downto 0); -- transmit register
signal TxParity : Std_logic; -- Parity Bit
signal DataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter
signal TRegE : Std_Logic; -- Transmit Register empty
signal TRegEDel : Std_Logic; -- Transmit Register empty
signal TRegEEdge : Std_Logic;
signal TxState : TxStateType;
signal TxDbit : Std_Logic;
begin
 
---------------------------------------------------------------------
-- Transmit Clock Edge Detection
-- A falling edge will produce a one clock cycle pulse
---------------------------------------------------------------------
txunit_clock_edge : process(Clk, Reset, TxClk, TxClkDel )
begin
if Reset = '1' then
TxClkDel <= TxClk;
TxClkEdge <= '0';
elsif Clk'event and Clk = '0' then
TxClkDel <= TxClk;
TxClkEdge <= TxClkDel and (not TxClk);
end if;
end process;
 
 
---------------------------------------------------------------------
-- Transmit Clock Divider
-- Advance the count only on an input clock pulse
---------------------------------------------------------------------
txunit_clock_divide : process(Clk, Reset, TxClkEdge, TxClkCnt )
begin
if Reset = '1' then
TxClkCnt <= "000000";
elsif Clk'event and Clk = '0' then
if TxClkEdge = '1' then
TxClkCnt <= TxClkCnt + "000001";
else
TxClkCnt <= TxClkCnt;
end if; -- TxClkEdge
end if; -- reset / clk
end process;
 
---------------------------------------------------------------------
-- Receiver Clock Selector
-- Select output then look for rising edge
---------------------------------------------------------------------
txunit_clock_select : process(Clk, Reset, BdFmt, TxClk, TxClkCnt,
TxBdDel, TxBdEdge )
begin
-- BdFmt
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
case BdFmt is
when "00" => -- Div by 1
TxBdClk <= TxClk;
when "01" => -- Div by 16
TxBdClk <= TxClkCnt(3);
when "10" => -- Div by 64
TxBdClk <= TxClkCnt(5);
when others => -- reset
TxBdClk <= '0';
end case;
 
if Reset = '1' then
TxBdDel <= TxBdClk;
TxBdEdge <= '0';
elsif Clk'event and Clk = '0' then
TxBdDel <= TxBdClk;
TxBdEdge <= TxBdClk and (not TxBdDel);
end if;
end process;
 
---------------------------------------------------------------------
-- Transmit Buffer Empty Edge
-- generate a negative edge pulse
---------------------------------------------------------------------
txunit_busy : process(Clk, Reset, TRegE, TRegEDel )
begin
if Reset = '1' then
TRegEDel <= '0';
TRegEEdge <= '0';
elsif Clk'event and Clk = '0' then
TRegEDel <= TRegE;
TRegEEdge <= TregEDel and (not TRegE ); -- falling edge
end if;
end process;
 
---------------------------------------------------------------------
-- Transmitter activation process
---------------------------------------------------------------------
txunit_write : process(Clk, Reset, LoadD, DAIn, TBufE, TRegEEdge )
begin
if Reset = '1' then
TBufE <= '1';
TBuff <= "00000000";
elsif Clk'event and Clk = '0' then
if LoadD = '1' then
TBuff <= DAIn;
TBufE <= '0';
else
TBuff <= TBuff;
if (TBufE = '0') and (TRegEEdge = '1') then
-- Once the transmitter is started
-- We can flag the buffer empty again.
TBufE <= '1';
else
TBufE <= TBufE;
end if;
end if;
end if; -- clk / reset
TBE <= TBufE;
 
end process;
 
-----------------------------------------------------------------------------
-- Implements the Tx unit
-----------------------------------------------------------------------------
txunit_transmit : process(Reset, Clk, TxState, TxDbit, TBuff, TReg,
TxBdEdge, TxParity, DataCnt, WdFmt,
TBufE, TRegE )
begin
if Reset = '1' then
TxDbit <= '1';
TReg <= "00000000";
TxParity <= '0';
DataCnt <= "0000";
TRegE <= '1';
TxState <= TxIdle_State;
elsif Clk'event and Clk = '0' then
if TxBdEdge = '1' then
case TxState is
when TxIdle_State => -- TxIdle_State (also 1st or 2nd Stop bit)
TxDbit <= '1';
TReg <= TBuff;
TxParity <= '0';
DataCnt <= "0000";
TRegE <= '1';
if TBufE = '0' then
TxState <= Start_State;
else
TxState <= TxIdle_State;
end if;
 
when Start_State =>
TxDbit <= '0'; -- Start bit
TReg <= TReg;
TxParity <= '0';
if WdFmt(2) = '0' then
DataCnt <= "0110"; -- 7 data + parity
else
DataCnt <= "0111"; -- 8 data
end if;
TRegE <= '0';
TxState <= Data_State;
 
when Data_State =>
TxDbit <= TReg(0);
TReg <= '1' & TReg(7 downto 1);
TxParity <= TxParity xor TReg(0);
TRegE <= '0';
DataCnt <= DataCnt - "0001";
if DataCnt = "0000" then
if (WdFmt(2) = '1') and (WdFmt(1) = '0') then
if WdFmt(0) = '0' then -- 8 data bits
TxState <= Stop_State; -- 2 stops
else
TxState <= TxIdle_State; -- 1 stop
end if;
else
TxState <= Parity_State; -- parity
end if;
else
TxState <= Data_State;
end if;
 
when Parity_State => -- 7/8 data + parity bit
if WdFmt(0) = '0' then
TxDbit <= not( TxParity ); -- even parity
else
TXDbit <= TxParity; -- odd parity
end if;
Treg <= Treg;
TxParity <= '0';
TRegE <= '0';
DataCnt <= "0000";
if WdFmt(1) = '0' then
TxState <= Stop_State; -- 2 stops
else
TxState <= TxIdle_State; -- 1 stop
end if;
 
when Stop_State => -- first stop bit
TxDbit <= '1'; -- 2 stop bits
Treg <= Treg;
TxParity <= '0';
DataCnt <= "0000";
TRegE <= '0';
TxState <= TxIdle_State;
 
when others => -- Undefined
TxDbit <= TxDbit;
Treg <= Treg;
TxParity <= '0';
DataCnt <= "0000";
TRegE <= TregE;
TxState <= TxIdle_State;
 
end case; -- TxState
 
else -- TxBdEdge
TxDbit <= TxDbit;
TReg <= TReg;
TxParity <= TxParity;
DataCnt <= DataCnt;
TRegE <= TRegE;
TxState <= TxState;
end if; -- TxBdEdge
end if; -- clk / reset
 
TxDat <= TxDbit;
end process;
 
end Behaviour; --=================== End of architecture ====================--
/trunk/rtl/vhdl/bootrom.vhd
0,0 → 1,167
-- FILE NAME: bootrom.vhdl
-- ENTITY NAME: boot_rom
-- ARCHITECTURE NAME: behave
-- REVISION: A
--
-- DESCRIPTION: 128 byte x 8 bit ROM
-- to boot a Monitor program on reset
--
--Written by John Kent for the mc6809 processor
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library work;
-- use work.memory.all;
 
entity boot_rom is
port (
addr : in std_logic_vector(6 downto 0);
data : out std_logic_vector(7 downto 0)
);
end entity boot_rom;
 
architecture basic of boot_rom is
constant width : integer := 8;
constant memsize : integer := 128;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"00010000", -- LDS #$F7FE
"11001110",
"11110111",
"11111110",
"10001110", -- LDX #$FF97
"11111111",
"10010111",
"00010000", -- LDY #$F000
"10001110",
"11110000",
"00000000",
"11000110", -- LDB #$61
"01100001",
"10100110", -- LDA ,X+ *** MOVELP
"10000000",
"10100111", -- STA ,Y+
"10100000",
"01011010", -- DECB
"00100110", -- BNE MOVELP
"11111001",
"01111110", -- JMP $F000
"11110000",
"00000000",
"10000110", -- LDA #$E0
"11100000",
"00011111", -- TFR A,DPR
"10001011",
"10001101", -- BSR WAITRDY
"01001001",
"10000110", -- LDA #$E0
"11100000",
"10010111", -- STA <$E016
"00010110",
"10001101", -- BSR WAITRDY
"01000011",
"10000110", -- LDA #$01
"00000001",
"10010111", -- STA <$E011
"00010001",
"10000110", -- LDA #$EF
"11101111",
"10010111", -- STA <$E017
"00010111",
"10001101", -- BSR WAITRDY
"00111001",
"00010000", -- LDY #$F800
"10001110",
"11111000",
"00000000",
"11000110", -- LDB #$7C
"01111100",
"10000110", -- LDA #$01 *** RDLP1
"00000001",
"10010111", -- STA <$E012
"00010010",
"11010111", -- STB <$E013
"00010011",
"10000110", -- LDA #$F4
"11110100",
"10010111", -- STA <$E014
"00010100",
"01001111", -- CLRA
"10010111", -- STA <$E015
"00010101",
"10001110", -- LDX #512
"00000010",
"00000000",
"10000110", -- LDA #$20
"00100000",
"10010111", -- STA <$E017
"00010111",
"10001101", -- BSR WAITRDY
"00011101",
"10001101", -- BSR WAITDRQ *** RDLP2
"00100110",
"10010110", -- LDA <$E010
"00010000",
"10100111", -- STA ,Y+
"10100000",
"00110000", -- LEAX -1,X
"00011111",
"10001100", -- CMPX #$0000
"00000000",
"00000000",
"00100110", -- BNE RDLP2
"11110011",
"10001101", -- BSR WAITRDY
"00001110",
"01011100", -- INCB
"11000001", -- CMPB #$80
"10000000",
"00100110", -- BNE RDLP1
"11010110",
"00001111", -- CLR <$E030
"00110000",
"01001111", -- CLRA
"00011111", -- TFR A,DPR
"10001011",
"01101110", -- JMP [$FFFE]
"10011111",
"11111111",
"11111110",
"10010110", -- LDA <$E017 *** WAITRDY
"00010111",
"00101011", -- BMI WAITRDY
"11111100",
"10010110", -- LDA <$E017
"00010111",
"10000101", -- BITA #$40
"01000000",
"00100111", -- BNE WAITRQY
"11110110",
"00111001", -- RTS
"10010110", -- LDA <$E017 *** WAITDRQ
"00010111",
"10000101", -- BITA #$08
"00001000",
"00100111", -- BEQ WAITDRQ
"11111010",
"00111001", -- RTS
"11111111", -- FDB $F800
"10000000",
"11111111", -- FDB $F800
"10000000",
"11111111", -- FDB $F800
"10000000",
"11111111", -- FDB $F800
"10000000"
);
begin
data <= rom_data(conv_integer(addr));
end architecture basic;
 
 
/trunk/rtl/vhdl/ps2_keyboard.vhd
0,0 → 1,787
---------------------------------------------------------------------------------------
--
-- Author: John Clayton
-- Date : April 30, 2001
-- Update: 4/30/01 copied this file from lcd_2.v (pared down).
-- Update: 5/24/01 changed the first module from "ps2_keyboard_receiver"
-- to "ps2_keyboard_interface"
-- Update: 5/29/01 Added input synchronizing flip-flops. Changed state
-- encoding (m1) for good operation after part config.
-- Update: 5/31/01 Added low drive strength and slow transitions to ps2_clk
-- and ps2_data in the constraints file. Added the signal
-- "tx_shifting_done" as distinguished from "rx_shifting_done."
-- Debugged the transmitter portion in the lab.
-- Update: 6/01/01 Added horizontal tab to the ascii output.
-- Update: 6/01/01 Added parameter TRAP_SHIFT_KEYS.
-- Update: 6/05/01 Debugged the "debounce" timer functionality.
-- Used 60usec timer as a "watchdog" timeout during
-- receive from the keyboard. This means that a keyboard
-- can now be "hot plugged" into the interface, without
-- messing up the bit_count, since the bit_count is reset
-- to zero during periods of inactivity anyway. This was
-- difficult to debug. I ended up using the logic analyzer,
-- and had to scratch my head quite a bit.
-- Update: 6/06/01 Removed extra comments before the input synchronizing
-- flip-flops. Used the correct parameter to size the
-- 5usec_timer_count. Changed the name of this file from
-- ps2.v to ps2_keyboard.v
-- Update: 6/06/01 Removed "&& q[7:0]" in output_strobe logic. Removed extra
-- commented out "else" condition in the shift register and
-- bit counter.
-- Update: 6/07/01 Changed default values for 60usec timer parameters so that
-- they correspond to 60usec for a 49.152MHz clock.
--
-- Converted to VHDL: 10 February 2004 - John Kent
--
--
--
-- Description
---------------------------------------------------------------------------------------
-- This is a state-machine driven serial-to-parallel and parallel-to-serial
-- interface to the ps2 style keyboard interface. The details of the operation
-- of the keyboard interface were obtained from the following website:
--
-- http:--www.beyondlogic.org/keyboard/keybrd.htm
--
-- Some aspects of the keyboard interface are not implemented (e.g, parity
-- checking for the receive side, and recognition of the various commands
-- which the keyboard sends out, such as "power on selt test passed," "Error"
-- and "Resend.") However, if the user wishes to recognize these reply
-- messages, the scan code output can always be used to extend functionality
-- as desired.
--
-- Note that the "Extended" (0xE0) and "Released" (0xF0) codes are recognized.
-- The rx interface provides separate indicator flags for these two conditions
-- with every valid character scan code which it provides. The shift keys are
-- also trapped by the interface, in order to provide correct uppercase ASCII
-- characters at the ascii output, although the scan codes for the shift keys
-- are still provided at the scan code output. So, the left/right ALT keys
-- can be differentiated by the presence of the rx_entended signal, while the
-- left/right shift keys are differentiable by the different scan codes
-- received.
--
-- The interface to the ps2 keyboard uses ps2_clk clock rates of
-- 30-40 kHz, dependent upon the keyboard itself. The rate at which the state
-- machine runs should be at least twice the rate of the ps2_clk, so that the
-- states can accurately follow the clock signal itself. Four times
-- oversampling is better. Say 200kHz at least. The upper limit for clocking
-- the state machine will undoubtedly be determined by delays in the logic
-- which decodes the scan codes into ASCII equivalents. The maximum speed
-- will be most likely many megahertz, depending upon target technology.
-- In order to run the state machine extremely fast, synchronizing flip-flops
-- have been added to the ps2_clk and ps2_data inputs of the state machine.
-- This avoids poor performance related to slow transitions of the inputs.
--
-- Because this is a bi-directional interface, while reading from the keyboard
-- the ps2_clk and ps2_data lines are used as inputs. While writing to the
-- keyboard, however (which may be done at any time. If writing interrupts a
-- read from the keyboard, the keyboard will buffer up its data, and send
-- it later) both the ps2_clk and ps2_data lines are occasionally pulled low,
-- and pullup resistors are used to bring the lines high again, by setting
-- the drivers to high impedance state.
--
-- The tx interface, for writing to the keyboard, does not provide any special
-- pre-processing. It simply transmits the 8-bit command value to the
-- keyboard.
--
-- Pullups MUST BE USED on the ps2_clk and ps2_data lines for this design,
-- whether they be internal to an FPGA I/O pad, or externally placed.
-- If internal pullups are used, they may be fairly weak, causing bounces
-- due to crosstalk, etc. There is a "debounce timer" implemented in order
-- to eliminate erroneous state transitions which would occur based on bounce.
--
-- Parameters are provided in order to configure and appropriately size the
-- counter of a 60 microsecond timer used in the transmitter, depending on
-- the clock frequency used. The 60 microsecond period is guaranteed to be
-- more than one period of the ps2_clk_s signal.
--
-- Also, a smaller 5 microsecond timer has been included for "debounce".
-- This is used because, with internal pullups on the ps2_clk and ps2_data
-- lines, there is some bouncing around which occurs
--
-- A parameter TRAP_SHIFT_KEYS allows the user to eliminate shift keypresses
-- from producing scan codes (along with their "undefined" ASCII equivalents)
-- at the output of the interface. If TRAP_SHIFT_KEYS is non-zero, the shift
-- key status will only be reported by rx_shift_key_on. No ascii or scan
-- codes will be reported for the shift keys. This is useful for those who
-- wish to use the ASCII data stream, and who don't want to have to "filter
-- out" the shift key codes.
--
---------------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity ps2_keyboard_interface is
port(
clk : in std_logic;
reset : in std_logic;
ps2_clk : inout std_logic;
ps2_data : inout std_logic;
rx_extended : out std_logic;
rx_released : out std_logic;
rx_shift_key_on : out std_logic;
-- rx_scan_code : out std_logic_vector(7 downto 0);
rx_ascii : out std_logic_vector(7 downto 0);
rx_data_ready : out std_logic; -- rx_read_o
rx_read : in std_logic; -- rx_read_ack_i
tx_data : in std_logic_vector(7 downto 0);
tx_write : in std_logic;
tx_write_ack : out std_logic;
tx_error_no_keyboard_ack : out std_logic
);
end ps2_keyboard_interface;
 
-------------------------------------------------------------------------------
-- Architecture for ps2 keyboard interface
-------------------------------------------------------------------------------
architecture my_ps2_keyboard of ps2_keyboard_interface is
-----------------------------------------------------------------------------
 
constant TOTAL_BITS : integer := 11;
constant EXTEND_CODE : integer := 16#E0#;
constant RELEASE_CODE : integer := 16#F0#;
constant LEFT_SHIFT : integer := 16#12#;
constant RIGHT_SHIFT : integer := 16#59#;
 
 
-- constants
 
-- The timer value can be up to (2^bits) inclusive.
-- Values for 49.152 MHz clock
--constant TIMER_60USEC_VALUE_PP : integer := 2950; -- Number of sys_clks for 60usec.
--constant TIMER_60USEC_BITS_PP : integer := 12; -- Number of bits needed for timer
--constant TIMER_5USEC_VALUE_PP : integer := 186; -- Number of sys_clks for debounce
--constant TIMER_5USEC_BITS_PP : integer := 8; -- Number of bits needed for timer
 
-- Values for 12.5 MHz Clock
constant TIMER_60USEC_VALUE_PP : integer := 750; -- Number of sys_clks for 60usec.
constant TIMER_60USEC_BITS_PP : integer := 10; -- Number of bits needed for timer
constant TIMER_5USEC_VALUE_PP : integer := 62; -- Number of sys_clks for debounce
constant TIMER_5USEC_BITS_PP : integer := 6; -- Number of bits needed for timer
 
constant TRAP_SHIFT_KEYS_PP : integer := 0; -- Default: No shift key trap.
 
-- State encodings, provided as constants
-- for flexibility to the one instantiating the module.
-- In general, the default values need not be changed.
 
-- State "m1_rx_clk_l" has been chosen on purpose. Since the input
-- synchronizing flip-flops initially contain zero, it takes one clk
-- for them to update to reflect the actual (idle = high) status of
-- the I/O lines from the keyboard. Therefore, choosing 0 for m1_rx_clk_l
-- allows the state machine to transition to m1_rx_clk_h when the true
-- values of the input signals become present at the outputs of the
-- synchronizing flip-flops. This initial transition is harmless, and it
-- eliminates the need for a "reset" pulse before the interface can operate.
 
type m1_type is ( m1_rx_clk_h, m1_rx_clk_l,
m1_tx_wait_clk_h, m1_tx_force_clk_l,
m1_tx_clk_h, m1_tx_clk_l,
m1_tx_wait_keyboard_ack, m1_tx_done_recovery,
m1_tx_error_no_keyboard_ack, m1_tx_rising_edge_marker,
m1_tx_first_wait_clk_h, m1_tx_first_wait_clk_l, m1_tx_reset_timer,
m1_rx_falling_edge_marker, m1_rx_rising_edge_marker );
 
type m2_type is ( m2_rx_data_ready_ack, m2_rx_data_ready );
 
-- Internal signal declarations
signal timer_60usec_done : std_logic;
signal timer_5usec_done : std_logic;
signal extended : std_logic;
signal released : std_logic;
signal shift_key_on : std_logic;
 
-- NOTE: These two signals used to be one. They
-- were split into two signals because of
-- shift key trapping. With shift key
-- trapping, no event is generated externally,
-- but the "hold" data must still be cleared
-- anyway regardless, in preparation for the
-- next scan codes.
signal rx_output_event : std_logic; -- Used only to clear: hold_released, hold_extended
signal rx_output_strobe : std_logic; -- Used to produce the actual output.
 
signal tx_parity_bit : std_logic;
signal rx_shifting_done : std_logic;
signal tx_shifting_done : std_logic;
signal shift_key_plus_code: std_logic_vector(11 downto 0);
 
signal q : std_logic_vector(TOTAL_BITS-1 downto 0);
signal m1_state : m1_type;
signal m1_next_state : m1_type;
signal m2_state : m2_type;
signal m2_next_state : m2_type;
signal bit_count : std_logic_vector(3 downto 0);
signal enable_timer_60usec: std_logic;
signal enable_timer_5usec : std_logic;
signal timer_60usec_count : std_logic_vector(TIMER_60USEC_BITS_PP-1 downto 0);
signal timer_5usec_count : std_logic_vector(TIMER_5USEC_BITS_PP-1 downto 0);
signal ascii : std_logic_vector(7 downto 0); -- "REG" type only because a case statement is used.
signal left_shift_key : std_logic;
signal right_shift_key : std_logic;
signal hold_extended : std_logic; -- Holds prior value, cleared at rx_output_strobe
signal hold_released : std_logic; -- Holds prior value, cleared at rx_output_strobe
signal ps2_clk_s : std_logic; -- Synchronous version of this input
signal ps2_data_s : std_logic; -- Synchronous version of this input
signal ps2_clk_hi_z : std_logic; -- Without keyboard, high Z equals 1 due to pullups.
signal ps2_data_hi_z : std_logic; -- Without keyboard, high Z equals 1 due to pullups.
signal tx_write_ack_o : std_logic;
 
begin
----------------------------------------------------------------------------
-- Module code
-- assign ps2_clk = ps2_clk_hi_z?1'bZ:1'b0;
-- assign ps2_data = ps2_data_hi_z?1'bZ:1'b0;
--
ps2_direction : process( ps2_clk_hi_z, ps2_data_hi_z )
begin
if( ps2_clk_hi_z = '1' ) then
ps2_clk <= 'Z';
else
ps2_clk <= '0';
end if;
if( ps2_data_hi_z = '1' ) then
ps2_data <= 'Z';
else
ps2_data <= '0';
end if;
end process;
-- Input "synchronizing" logic -- synchronizes the inputs to the state
-- machine clock, thus avoiding errors related to
-- spurious state machine transitions.
ps2_synch : process(clk, ps2_clk, ps2_data)
begin
if clk'event and clk='1' then
ps2_clk_s <= ps2_clk;
ps2_data_s <= ps2_data;
end if;
end process;
 
-- State register
m1_state_register : process( clk, reset, m1_state )
begin
if clk'event and clk='1' then
if (reset = '1') then
m1_state <= m1_rx_clk_h;
else
m1_state <= m1_next_state;
end if;
end if;
end process;
 
m1_state_logic : process( m1_state, q,
tx_shifting_done, tx_write,
ps2_clk_s, ps2_data_s,
timer_60usec_done, timer_5usec_done )
begin
-- Output signals default to this value, unless changed in a state condition.
ps2_clk_hi_z <= '1';
ps2_data_hi_z <= '1';
tx_error_no_keyboard_ack <= '0';
enable_timer_60usec <= '0';
enable_timer_5usec <= '0';
 
case (m1_state) is
when m1_rx_clk_h =>
enable_timer_60usec <= '1';
if (tx_write = '1') then
m1_next_state <= m1_tx_reset_timer;
elsif (ps2_clk_s = '0') then
m1_next_state <= m1_rx_falling_edge_marker;
else
m1_next_state <= m1_rx_clk_h;
end if;
when m1_rx_falling_edge_marker =>
enable_timer_60usec <= '0';
m1_next_state <= m1_rx_clk_l;
 
when m1_rx_rising_edge_marker =>
enable_timer_60usec <= '0';
m1_next_state <= m1_rx_clk_h;
 
 
when m1_rx_clk_l =>
enable_timer_60usec <= '1';
if (tx_write = '1') then
m1_next_state <= m1_tx_reset_timer;
elsif (ps2_clk_s = '1') then
m1_next_state <= m1_rx_rising_edge_marker;
else
m1_next_state <= m1_rx_clk_l;
end if;
 
when m1_tx_reset_timer =>
enable_timer_60usec <= '0';
m1_next_state <= m1_tx_force_clk_l;
 
when m1_tx_force_clk_l =>
enable_timer_60usec <= '1';
ps2_clk_hi_z <= '0'; -- Force the ps2_clk line low.
if (timer_60usec_done = '1') then
m1_next_state <= m1_tx_first_wait_clk_h;
else
m1_next_state <= m1_tx_force_clk_l;
end if;
 
when m1_tx_first_wait_clk_h =>
enable_timer_5usec <= '1';
ps2_data_hi_z <= '0'; -- Start bit.
if (ps2_clk_s = '0') and (timer_5usec_done = '1') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_first_wait_clk_h;
end if;
-- This state must be included because the device might possibly
-- delay for up to 10 milliseconds before beginning its clock pulses.
-- During that waiting time, we cannot drive the data (q[0]) because it
-- is possibly 1, which would cause the keyboard to abort its receive
-- and the expected clocks would then never be generated.
when m1_tx_first_wait_clk_l =>
ps2_data_hi_z <= '0';
if (ps2_clk_s = '0') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_first_wait_clk_l;
end if;
 
when m1_tx_wait_clk_h =>
enable_timer_5usec <= '1';
ps2_data_hi_z <= q(0);
if (ps2_clk_s = '1') and (timer_5usec_done = '1') then
m1_next_state <= m1_tx_rising_edge_marker;
else
m1_next_state <= m1_tx_wait_clk_h;
end if;
 
when m1_tx_rising_edge_marker =>
ps2_data_hi_z <= q(0);
m1_next_state <= m1_tx_clk_h;
 
when m1_tx_clk_h =>
ps2_data_hi_z <= q(0);
if (tx_shifting_done = '1') then
m1_next_state <= m1_tx_wait_keyboard_ack;
elsif (ps2_clk_s = '0') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_clk_h;
end if;
 
when m1_tx_clk_l =>
ps2_data_hi_z <= q(0);
if (ps2_clk_s = '1') then
m1_next_state <= m1_tx_wait_clk_h;
else
m1_next_state <= m1_tx_clk_l;
end if;
 
when m1_tx_wait_keyboard_ack =>
if (ps2_clk_s = '0') and (ps2_data_s = '1') then
m1_next_state <= m1_tx_error_no_keyboard_ack;
elsif (ps2_clk_s = '0') and (ps2_data_s = '0') then
m1_next_state <= m1_tx_done_recovery;
else
m1_next_state <= m1_tx_wait_keyboard_ack;
end if;
 
when m1_tx_done_recovery =>
if (ps2_clk_s = '1') and (ps2_data_s = '1') then
m1_next_state <= m1_rx_clk_h;
else
m1_next_state <= m1_tx_done_recovery;
end if;
 
when m1_tx_error_no_keyboard_ack =>
tx_error_no_keyboard_ack <= '1';
if (ps2_clk_s = '1') and (ps2_data_s ='1') then
m1_next_state <= m1_rx_clk_h;
else
m1_next_state <= m1_tx_error_no_keyboard_ack;
end if;
 
when others =>
m1_next_state <= m1_rx_clk_h;
end case;
end process;
 
-- State register
m2_state_register : process( clk )
begin
if clk'event and clk='1' then
if (reset = '1') then
m2_state <= m2_rx_data_ready_ack;
else
m2_state <= m2_next_state;
end if;
end if;
end process;
 
-- State transition logic
m2_state_logic : process(m2_state, rx_output_strobe, rx_read)
begin
case (m2_state) is
when m2_rx_data_ready_ack =>
rx_data_ready <= '0';
if (rx_output_strobe = '1') then
m2_next_state <= m2_rx_data_ready;
else
m2_next_state <= m2_rx_data_ready_ack;
end if;
 
when m2_rx_data_ready =>
rx_data_ready <= '1';
if (rx_read = '1') then
m2_next_state <= m2_rx_data_ready_ack;
else
m2_next_state <= m2_rx_data_ready;
end if;
 
when others =>
m2_next_state <= m2_rx_data_ready_ack;
end case;
end process;
 
-- This is the bit counter
bit_counter: process(clk, reset, m1_state, bit_count )
begin
if clk'event and clk = '1' then
if ( reset = '1' ) or
( rx_shifting_done = '1' ) or
(m1_state = m1_tx_wait_keyboard_ack) then -- After tx is done.
bit_count <= "0000"; -- normal reset
elsif (timer_60usec_done = '1' ) and
(m1_state = m1_rx_clk_h) and
(ps2_clk_s = '1') then
bit_count <= "0000"; -- rx watchdog timer reset
elsif (m1_state = m1_rx_falling_edge_marker) or -- increment for rx
(m1_state = m1_tx_rising_edge_marker) then -- increment for tx
bit_count <= bit_count + 1;
end if;
end if;
end process;
 
assign: process( bit_count, tx_write, tx_write_ack_o, m1_state )
begin
if (bit_count = TOTAL_BITS) then
rx_shifting_done <= '1';
else
rx_shifting_done <= '0';
end if;
 
if (bit_count = (TOTAL_BITS-1)) then
tx_shifting_done <= '1';
else
tx_shifting_done <= '0';
end if;
 
-- This is the signal which enables loading of the shift register.
-- It also indicates "ack" to the device writing to the transmitter.
if ((tx_write = '1') and (m1_state = m1_rx_clk_h)) or
((tx_write = '1') and (m1_state = m1_rx_clk_l)) then
tx_write_ack_o <= '1';
else
tx_write_ack_o <= '0';
end if;
tx_write_ack <= tx_write_ack_o;
end process;
 
-- This is the ODD parity bit for the transmitted word.
-- assign tx_parity_bit = ~^tx_data;
--
tx_parity_bit <= not( tx_data(7) xor tx_data(6) xor tx_data(5) xor tx_data(4) xor
tx_data(7) xor tx_data(6) xor tx_data(5) xor tx_data(4) );
 
-- This is the shift register
q_shift : process(clk, tx_write_ack_o, tx_parity_bit, tx_data,
m1_state, q, ps2_data_s, rx_shifting_done )
begin
if clk'event and clk='1' then
if (reset = '1') then
q <= "00000000000";
elsif (tx_write_ack_o = '1') then
q <= "1" & tx_parity_bit & tx_data & "0";
elsif ( (m1_state = m1_rx_falling_edge_marker) or
(m1_state = m1_tx_rising_edge_marker) ) then
q <= ps2_data_s & q((TOTAL_BITS-1) downto 1);
end if;
end if;
 
-- Create the signals which indicate special scan codes received.
-- These are the "unlatched versions."
if (q(8 downto 1) = EXTEND_CODE) and (rx_shifting_done = '1') then
extended <= '1';
else
extended <= '0';
end if;
if (q(8 downto 1) = RELEASE_CODE) and (rx_shifting_done = '1') then
released <= '1';
else
released <= '0';
end if;
end process;
 
-- This is the 60usec timer counter
timer60usec: process(clk, enable_timer_60usec, timer_60usec_count)
begin
if clk'event and clk = '1' then
if (enable_timer_60usec = '0') then
timer_60usec_count <= "0000000000";
elsif (timer_60usec_done = '0') then
timer_60usec_count <= timer_60usec_count + 1;
end if;
end if;
 
if (timer_60usec_count = (TIMER_60USEC_VALUE_PP - 1)) then
timer_60usec_done <= '1';
else
timer_60usec_done <= '0';
end if;
end process;
 
-- This is the 5usec timer counter
timer5usec : process(clk, enable_timer_5usec, timer_5usec_count )
begin
if clk'event and clk = '1' then
if (enable_timer_5usec = '0') then
timer_5usec_count <= "000000";
elsif (timer_5usec_done = '0') then
timer_5usec_count <= timer_5usec_count + 1;
end if;
end if;
 
if( timer_5usec_count = (TIMER_5USEC_VALUE_PP - 1)) then
timer_5usec_done <= '1';
else
timer_5usec_done <= '0';
end if;
end process;
 
 
-- Store the special scan code status bits
-- Not the final output, but an intermediate storage place,
-- until the entire set of output data can be assembled.
special_scan : process(clk, reset, rx_output_event, rx_shifting_done, extended, released )
begin
if clk'event and clk='1' then
if (reset = '1') or (rx_output_event = '1') then
hold_extended <= '0';
hold_released <= '0';
else
if (rx_shifting_done = '1') and (extended = '1') then
hold_extended <= '1';
end if;
if (rx_shifting_done = '1') and (released = '1') then
hold_released <= '1';
end if;
end if;
end if;
end process;
 
 
-- These bits contain the status of the two shift keys
left_shift_proc : process(clk, reset, q, rx_shifting_done, hold_released )
begin
if clk'event and clk = '1' then
if (reset = '1') then
left_shift_key <= '0';
elsif (q(8 downto 1) = LEFT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '0') then
left_shift_key <= '1';
elsif (q(8 downto 1) = LEFT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '1') then
left_shift_key <= '0';
end if;
end if;
end process;
 
right_shift_proc : process(clk, reset, q, rx_shifting_done, hold_released )
begin
if clk'event and clk = '1' then
if (reset = '1') then
right_shift_key <= '0';
elsif (q(8 downto 1) = RIGHT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '0') then
right_shift_key <= '1';
elsif (q(8 downto 1) = RIGHT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '1') then
right_shift_key <= '0';
end if;
end if;
end process;
 
shift_key_on <= left_shift_key or right_shift_key;
rx_shift_key_on <= shift_key_on;
 
-- Output the special scan code flags, the scan code and the ascii
special_scan_proc : process(clk, reset, hold_extended, hold_released, q, ascii )
begin
if clk'event and clk = '1' then
if (reset = '1') then
rx_extended <= '0';
rx_released <= '0';
-- rx_scan_code <= "00000000";
rx_ascii <= "00000000";
elsif (rx_output_strobe = '1') then
rx_extended <= hold_extended;
rx_released <= hold_released;
-- rx_scan_code <= q(8 downto 1);
rx_ascii <= ascii;
end if;
end if;
end process;
 
-- Store the final rx output data only when all extend and release codes
-- are received and the next (actual key) scan code is also ready.
-- (the presence of rx_extended or rx_released refers to the
-- the current latest scan code received, not the previously latched flags.)
 
rx_output_proc : process( rx_shifting_done, extended, released, q )
begin
if (rx_shifting_done = '1') and (extended = '0') and (released = '0') then
rx_output_event <= '1';
else
rx_output_event <= '0';
end if;
 
if (rx_shifting_done = '1') and (extended = '0') and (released = '0') and
( (TRAP_SHIFT_KEYS_PP = 0) or
( (q(8 downto 1) /= RIGHT_SHIFT) and (q(8 downto 1) /= LEFT_SHIFT) ) )then
rx_output_strobe <= '1';
else
rx_output_strobe <= '0';
end if;
end process;
 
 
-- This part translates the scan code into an ASCII value...
-- Only the ASCII codes which I considered important have been included.
-- if you want more, just add the appropriate case statement lines...
-- (You will need to know the keyboard scan codes you wish to assign.)
-- The entries are listed in ascending order of ASCII value.
shift_key_plus_code <= "000" & shift_key_on & q(8 downto 1);
 
shift_map : process( shift_key_plus_code )
begin
case (shift_key_plus_code) is
when x"066" => ascii <= x"08"; -- Backspace ("backspace" key)
when x"166" => ascii <= x"08"; -- Backspace ("backspace" key)
when x"00d" => ascii <= x"09"; -- Horizontal Tab
when x"10d" => ascii <= x"09"; -- Horizontal Tab
when x"05a" => ascii <= x"0d"; -- Carriage return ("enter" key)
when x"15a" => ascii <= x"0d"; -- Carriage return ("enter" key)
when x"076" => ascii <= x"1b"; -- Escape ("esc" key)
when x"176" => ascii <= x"1b"; -- Escape ("esc" key)
when x"029" => ascii <= x"20"; -- Space
when x"129" => ascii <= x"20"; -- Space
when x"116" => ascii <= x"21"; -- !
when x"152" => ascii <= x"22"; -- "
when x"126" => ascii <= x"23"; -- #
when x"125" => ascii <= x"24"; -- $
when x"12e" => ascii <= x"25"; -- %
when x"13d" => ascii <= x"26"; -- &
when x"052" => ascii <= x"27"; -- '
when x"146" => ascii <= x"28"; -- (
when x"145" => ascii <= x"29"; -- )
when x"13e" => ascii <= x"2a"; -- *
when x"155" => ascii <= x"2b"; -- +
when x"041" => ascii <= x"2c"; -- ,
when x"04e" => ascii <= x"2d"; -- -
when x"049" => ascii <= x"2e"; -- .
when x"04a" => ascii <= x"2f"; -- /
when x"045" => ascii <= x"30"; -- 0
when x"016" => ascii <= x"31"; -- 1
when x"01e" => ascii <= x"32"; -- 2
when x"026" => ascii <= x"33"; -- 3
when x"025" => ascii <= x"34"; -- 4
when x"02e" => ascii <= x"35"; -- 5
when x"036" => ascii <= x"36"; -- 6
when x"03d" => ascii <= x"37"; -- 7
when x"03e" => ascii <= x"38"; -- 8
when x"046" => ascii <= x"39"; -- 9
when x"14c" => ascii <= x"3a"; -- :
when x"04c" => ascii <= x"3b"; -- ;
when x"141" => ascii <= x"3c"; -- <
when x"055" => ascii <= x"3d"; -- =
when x"149" => ascii <= x"3e"; -- >
when x"14a" => ascii <= x"3f"; -- ?
when x"11e" => ascii <= x"40"; -- @
when x"11c" => ascii <= x"41"; -- A
when x"132" => ascii <= x"42"; -- B
when x"121" => ascii <= x"43"; -- C
when x"123" => ascii <= x"44"; -- D
when x"124" => ascii <= x"45"; -- E
when x"12b" => ascii <= x"46"; -- F
when x"134" => ascii <= x"47"; -- G
when x"133" => ascii <= x"48"; -- H
when x"143" => ascii <= x"49"; -- I
when x"13b" => ascii <= x"4a"; -- J
when x"142" => ascii <= x"4b"; -- K
when x"14b" => ascii <= x"4c"; -- L
when x"13a" => ascii <= x"4d"; -- M
when x"131" => ascii <= x"4e"; -- N
when x"144" => ascii <= x"4f"; -- O
when x"14d" => ascii <= x"50"; -- P
when x"115" => ascii <= x"51"; -- Q
when x"12d" => ascii <= x"52"; -- R
when x"11b" => ascii <= x"53"; -- S
when x"12c" => ascii <= x"54"; -- T
when x"13c" => ascii <= x"55"; -- U
when x"12a" => ascii <= x"56"; -- V
when x"11d" => ascii <= x"57"; -- W
when x"122" => ascii <= x"58"; -- X
when x"135" => ascii <= x"59"; -- Y
when x"11a" => ascii <= x"5a"; -- Z
when x"054" => ascii <= x"5b"; -- [
when x"05d" => ascii <= x"5c"; -- \
when x"05b" => ascii <= x"5d"; -- ]
when x"136" => ascii <= x"5e"; -- ^
when x"14e" => ascii <= x"5f"; -- _
when x"00e" => ascii <= x"60"; -- `
when x"01c" => ascii <= x"61"; -- a
when x"032" => ascii <= x"62"; -- b
when x"021" => ascii <= x"63"; -- c
when x"023" => ascii <= x"64"; -- d
when x"024" => ascii <= x"65"; -- e
when x"02b" => ascii <= x"66"; -- f
when x"034" => ascii <= x"67"; -- g
when x"033" => ascii <= x"68"; -- h
when x"043" => ascii <= x"69"; -- i
when x"03b" => ascii <= x"6a"; -- j
when x"042" => ascii <= x"6b"; -- k
when x"04b" => ascii <= x"6c"; -- l
when x"03a" => ascii <= x"6d"; -- m
when x"031" => ascii <= x"6e"; -- n
when x"044" => ascii <= x"6f"; -- o
when x"04d" => ascii <= x"70"; -- p
when x"015" => ascii <= x"71"; -- q
when x"02d" => ascii <= x"72"; -- r
when x"01b" => ascii <= x"73"; -- s
when x"02c" => ascii <= x"74"; -- t
when x"03c" => ascii <= x"75"; -- u
when x"02a" => ascii <= x"76"; -- v
when x"01d" => ascii <= x"77"; -- w
when x"022" => ascii <= x"78"; -- x
when x"035" => ascii <= x"79"; -- y
when x"01a" => ascii <= x"7a"; -- z
when x"154" => ascii <= x"7b"; -- {
when x"15d" => ascii <= x"7c"; -- |
when x"15b" => ascii <= x"7d"; -- }
when x"10e" => ascii <= x"7e"; -- ~
when x"071" => ascii <= x"7f"; -- (Delete OR DEL on numeric keypad)
when x"171" => ascii <= x"7f"; -- (Delete OR DEL on numeric keypad)
when others => ascii <= x"2e"; -- '.' used for unlisted characters.
end case;
end process;
 
end my_ps2_keyboard;
/trunk/rtl/vhdl/vdu8.vhd
0,0 → 1,471
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
 
--
--
-- Video Display terminal
-- John Kent
-- 11th February 2004
-- Assumes a pixel chock of 19.8 MHz
-- with a character display of 64 characters across
-- by 30 characters down.
--
entity vdu is
port(
-- control register interface
vdu_clk_in : in std_logic;
vdu_clk_out : out std_logic;
vdu_rst : in std_logic;
vdu_cs : in std_logic;
vdu_rw : in std_logic;
vdu_addr : in std_logic_vector(2 downto 0);
vdu_data_in : in std_logic_vector(7 downto 0);
vdu_data_out : out std_logic_vector(7 downto 0);
 
-- vga port connections
vga_red0_o : out std_logic;
vga_red1_o : out std_logic;
vga_green0_o : out std_logic;
vga_green1_o : out std_logic;
vga_blue0_o : out std_logic;
vga_blue1_o : out std_logic;
vga_hsync_o : out std_logic;
vga_vsync_o : out std_logic
);
end vdu;
 
architecture arch of vdu is
 
constant HI: std_logic := '1';
constant LO: std_logic := '0';
 
signal horiz_sync : std_logic;
signal vert_sync : std_logic;
signal cursor_on_v : std_logic;
signal cursor_on_h : std_logic;
signal video_on_v : std_logic;
signal video_on_h : std_logic;
signal h_count : std_logic_vector(9 downto 0);
signal v_count : std_logic_vector(9 downto 0);
signal blink_count : std_logic_vector(22 downto 0);
--
-- Character generator ROM
--
signal char_cs : std_logic;
signal char_rw : std_logic;
signal char_addr : std_logic_vector(9 downto 0);
signal char_data_in : std_logic_vector(7 downto 0);
signal char_data_out : std_logic_vector(7 downto 0);
 
--
-- Control Registers
--
signal reg_character : std_logic_vector(7 downto 0);
signal reg_colour : std_logic_vector(7 downto 0);
signal reg_hcursor : std_logic_vector(5 downto 0); -- 64 columns
signal reg_vcursor : std_logic_vector(4 downto 0); -- 32 rows
signal reg_voffset : std_logic_vector(4 downto 0); -- 32 rows
--
-- Video Shift register
--
signal vga_shift : std_logic_vector(7 downto 0);
signal vga_colour : std_logic_vector(7 downto 0);
signal vga_colour1 : std_logic_vector(7 downto 0);
signal cursor_on : std_logic;
signal cursor_on1 : std_logic;
signal video_on : std_logic;
signal video_on1 : std_logic;
--
-- vga character ram access bus
--
signal vga_cs : std_logic;
signal vga_rw : std_logic;
signal vga_addr : std_logic_vector(10 downto 0); -- 2K byte character buffer
signal vga_data_out : std_logic_vector(7 downto 0);
signal attr_data_out : std_logic_vector(7 downto 0); -- 2K byte atrribute buffer
--
-- Character write handshake signals
--
signal req_write : std_logic; -- request character/attribute write
signal ack_write : std_logic;
 
component char_rom
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector (9 downto 0);
wdata : in std_logic_vector (7 downto 0);
rdata : out std_logic_vector (7 downto 0)
);
end component;
 
component ram_2k
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector (10 downto 0);
wdata : in std_logic_vector (7 downto 0);
rdata : out std_logic_vector (7 downto 0)
);
end component;
 
component BUFG
port (
i: in std_logic;
o: out std_logic
);
end component;
 
begin
 
--
-- instantiate Character generator ROM
--
vdu_char_rom: char_rom
port map(
clk => vdu_clk_in,
rst => vdu_rst,
cs => char_cs,
rw => char_rw,
addr => char_addr,
wdata => char_data_in,
rdata => char_data_out
);
 
--
-- Character buffer RAM
--
char_buff_ram: ram_2k
port map(
clk => vdu_clk_in,
rst => vdu_rst,
cs => vga_cs,
rw => vga_rw,
addr => vga_addr,
wdata => reg_character,
rdata => vga_data_out
);
 
--
-- Attribute (colour) RAM buffer
--
attr_buff_ram: ram_2k
port map(
clk => vdu_clk_in,
rst => vdu_rst,
cs => vga_cs,
rw => vga_rw,
addr => vga_addr,
wdata => reg_colour,
rdata => attr_data_out
);
 
clk_buffer : BUFG port map(
i => h_count(0),
o => vdu_clk_out
);
 
--
-- CPU Write interface
--
vga_cpu_write : process( vdu_clk_in, vdu_rst, vdu_cs, vdu_rw, vdu_addr, vdu_data_in,
reg_character, reg_colour, reg_hcursor, reg_vcursor,
req_write, ack_write )
begin
if( vdu_rst = '1' ) then
reg_character <= "00000000";
reg_colour <= "00001111";
reg_hcursor <= "000000";
reg_vcursor <= "00000";
reg_voffset <= "00000";
req_write <= '0';
elsif vdu_clk_in'event and vdu_clk_in='0' then
if (vdu_cs = '1') and (vdu_rw = '0') then
case vdu_addr is
when "000" =>
reg_character <= vdu_data_in;
reg_colour <= reg_colour;
reg_hcursor <= reg_hcursor;
reg_vcursor <= reg_vcursor;
reg_voffset <= reg_voffset;
req_write <= '1';
when "001" =>
reg_character <= reg_character;
reg_colour <= vdu_data_in;
reg_hcursor <= reg_hcursor;
reg_vcursor <= reg_vcursor;
reg_voffset <= reg_voffset;
req_write <= '1';
when "010" =>
reg_character <= reg_character;
reg_colour <= reg_colour;
reg_hcursor <= vdu_data_in(5 downto 0);
reg_vcursor <= reg_vcursor;
reg_voffset <= reg_voffset;
req_write <= req_write;
when "011" =>
reg_character <= reg_character;
reg_colour <= reg_colour;
reg_hcursor <= reg_hcursor;
reg_vcursor <= vdu_data_in(4 downto 0);
reg_voffset <= reg_voffset;
req_write <= req_write;
when others =>
reg_character <= reg_character;
reg_colour <= reg_colour;
reg_hcursor <= reg_hcursor;
reg_vcursor <= reg_vcursor;
reg_voffset <= vdu_data_in(4 downto 0);
req_write <= req_write;
end case;
else
reg_character <= reg_character;
reg_colour <= reg_colour;
reg_hcursor <= reg_hcursor;
reg_vcursor <= reg_vcursor;
reg_voffset <= reg_voffset;
 
if (req_write = '1') and (ack_write = '1') then
req_write <= '0';
else
req_write <= req_write;
end if;
 
end if;
end if;
end process;
--
-- CPU Read interface
--
vga_cpu_read : process( vdu_addr, vdu_cs,
reg_character, reg_colour, reg_hcursor, reg_vcursor )
begin
case vdu_addr is
when "000" =>
vdu_data_out <= reg_character;
when "001" =>
vdu_data_out <= reg_colour;
when "010" =>
vdu_data_out <= "00" & reg_hcursor;
when "011" =>
vdu_data_out <= "000" & reg_vcursor;
when others =>
vdu_data_out <= "000" & reg_voffset;
end case;
end process;
 
--
-- Video memory access
--
vga_addr_proc : process( reg_hcursor, reg_vcursor, reg_character, reg_colour,
h_count, v_count, req_write )
begin
case h_count(2 downto 0) is
when "001" => -- always write cursor data on 1 count
vga_cs <= req_write;
vga_rw <= '0';
vga_addr(5 downto 0) <= reg_hcursor;
vga_addr(10 downto 6) <= reg_vcursor;
when "110" => -- always read display character on 6 count
vga_cs <= '1';
vga_rw <= '1';
vga_addr(5 downto 0) <= h_count(8 downto 3);
vga_addr(10 downto 6) <= v_count(8 downto 4) + reg_voffset(4 downto 0);
when others => -- other 6 cycles free
vga_cs <= '0';
vga_rw <= '1';
vga_addr(5 downto 0) <= h_count(8 downto 3);
vga_addr(10 downto 6) <= v_count(8 downto 4) + reg_voffset(4 downto 0);
end case;
end process;
--
-- Video shift register
--
vga_shift_proc : process( vdu_clk_in, char_data_out,
video_on, video_on1, cursor_on, cursor_on1,
vga_colour, vga_colour1, vga_shift,
reg_hcursor, reg_vcursor, reg_character, reg_colour,
h_count, v_count,
req_write, ack_write )
begin
if (vdu_rst = '1') then
ack_write <= '0';
vga_colour <= "00001111";
vga_shift <= "00000000";
vga_red0_o <= '0';
vga_green0_o <= '0';
vga_blue0_o <= '0';
vga_red1_o <= '0';
vga_green1_o <= '0';
vga_blue1_o <= '0';
-- Put all video signals through DFFs to elminate any delays that cause a blurry image
elsif vdu_clk_in'event and vdu_clk_in='0' then
 
case h_count(2 downto 0) is
when "001" => -- always write cursor data on 1 count
if (req_write = '1') and (ack_write = '0') then
ack_write <= '1';
else
ack_write <= '0';
end if;
when others => -- other 4 cycles CPU is free to run.
ack_write <= ack_write;
end case;
 
if h_count(2 downto 0) = "111" then
vga_colour1 <= attr_data_out;
else
vga_colour1 <= vga_colour1;
end if;
 
if h_count(2 downto 0) = "000" then
video_on <= video_on1;
cursor_on <= cursor_on1;
vga_colour <= vga_colour1;
vga_shift <= char_data_out;
else
video_on <= video_on;
cursor_on <= cursor_on;
vga_colour <= vga_colour;
vga_shift <= vga_shift(6 downto 0) & '0';
end if;
 
--
-- Colour mask is
-- 7 6 5 4 3 2 1 0
-- BI BG BB BR FI FG FB FR
--
if vga_shift(7) = (not cursor_on) then
if vga_colour(3) = '0' then
vga_red0_o <= video_on and vga_colour(0);
vga_green0_o <= video_on and vga_colour(1);
vga_blue0_o <= video_on and vga_colour(2);
vga_red1_o <= '0';
vga_green1_o <= '0';
vga_blue1_o <= '0';
else
vga_red0_o <= '0';
vga_green0_o <= '0';
vga_blue0_o <= '0';
vga_red1_o <= video_on and vga_colour(0);
vga_green1_o <= video_on and vga_colour(1);
vga_blue1_o <= video_on and vga_colour(2);
end if;
else
if vga_colour(7) = '0' then
vga_red0_o <= video_on and vga_colour(4);
vga_green0_o <= video_on and vga_colour(5);
vga_blue0_o <= video_on and vga_colour(6);
vga_red1_o <= '0';
vga_green1_o <= '0';
vga_blue1_o <= '0';
else
vga_red0_o <= '0';
vga_green0_o <= '0';
vga_blue0_o <= '0';
vga_red1_o <= video_on and vga_colour(4);
vga_green1_o <= video_on and vga_colour(5);
vga_blue1_o <= video_on and vga_colour(6);
end if;
end if;
end if;
end process;
 
 
--
-- Sync generator & timing process
-- Generate Horizontal and Vertical Timing Signals for Video Signal
--
vga_sync: PROCESS(vdu_clk_in, h_count, v_count, horiz_sync, vert_sync )
BEGIN
if vdu_clk_in'event and vdu_clk_in='0' then
--
-- H_count counts pixels (256 + extra time for sync signals)
--
-- Horiz_sync ------------------------------------__________--------
-- H_count 0 512 528 604 639
--
IF (h_count = 639) THEN
h_count <= "0000000000";
ELSE
h_count <= h_count + 1;
END IF;
--
-- Generate Horizontal Sync Signal using H_count
--
IF (h_count <= 604) AND (h_count >= 528) THEN
horiz_sync <= '0';
ELSE
horiz_sync <= '1';
END IF;
--
-- V_count counts rows of pixels (480 + extra time for sync signals)
--
-- Vert_sync -----------------------------------------------_______------------
-- V_count 0 480 493-494 524
--
IF (v_count >= 588) AND (h_count >= 566) THEN
v_count <= "0000000000";
ELSIF (h_count = 283) THEN
v_count <= v_count + 1;
END IF;
--
-- Generate Vertical Sync Signal using V_count
--
IF (v_count <= 558) AND (v_count >= 557) THEN
vert_sync <= '0';
ELSE
vert_sync <= '1';
END IF;
 
-- Generate Video on Screen Signals for Pixel Data
IF (h_count <= 511) THEN
video_on_h <= '1';
ELSE
video_on_h <= '0';
END IF;
 
IF (v_count <= 511) THEN
video_on_v <= '1';
ELSE
video_on_v <= '0';
END IF;
 
 
if (h_count(8 downto 3) = reg_hcursor(5 downto 0)) then
cursor_on_h <= '1';
else
cursor_on_h <= '0';
end if;
 
if (v_count(8 downto 4) = reg_vcursor(4 downto 0)) then
cursor_on_v <= '1';
else
cursor_on_v <= '0';
end if;
-- cursor_on is only active when on selected character
blink_count <= blink_count + 1;
end if;
END PROCESS;
 
char_cs <= '1';
char_rw <= '1';
char_addr(2 downto 0) <= v_count(3 downto 1);
char_addr(9 downto 3) <= vga_data_out(6 downto 0);
char_data_in <= "00000000";
 
-- video_on is high only when RGB data is displayed
video_on1 <= video_on_H AND video_on_V;
cursor_on1 <= cursor_on_h and cursor_on_v and blink_count(21);
 
vga_hsync_o <= horiz_sync;
vga_vsync_o <= vert_sync;
 
end arch;
/trunk/rtl/vhdl/system09.ucf
43,246 → 43,188
#NET "cf_iordy" LOC = "P48" ; #J2-18
NET "cf_rst_n" LOC = "P49" ; #J2-19
#
# I/O Port
# For B5-Peripheral-Connectors
# Connector C
#
#NET "porta<0>" LOC = "p55" ; #pin 3
#NET "porta<1>" LOC = "p56" ; #pin 4
#NET "porta<2>" LOC = "p58" ; #pin 5
#NET "porta<3>" LOC = "p59" ; #pin 6
#NET "porta<4>" LOC = "p60" ; #pin 7
#NET "porta<5>" LOC = "p61" ; #pin 8
#NET "porta<6>" LOC = "p62" ; #pin 8
#NET "porta<7>" LOC = "p63" ; #pin 10
#NET "portb<0>" LOC = "p64" ; #pin 11
#NET "portb<1>" LOC = "p68" ; #pin 12
#NET "portb<2>" LOC = "p69" ; #pin 13
#NET "portb<3>" LOC = "p70" ; #pin 14
#NET "portb<4>" LOC = "p71" ; #pin 15
#NET "portb<5>" LOC = "p73" ; #pin 16
#NET "portb<6>" LOC = "p74" ; #pin 17
#NET "portb<7>" LOC = "p75" ; #pin 18
#NET "timer_out" LOC = "p81" ; #pin 19
NET "v_drive" LOC = "p55" ; #pin 3
NET "h_drive" LOC = "p56" ; #pin 4
NET "blue_lo" LOC = "p58" ; #pin 5
NET "blue_hi" LOC = "p59" ; #pin 6
NET "green_lo" LOC = "p60" ; #pin 7
NET "green_hi" LOC = "p61" ; #pin 8
NET "red_lo" LOC = "p62" ; #pin 9
NET "red_hi" LOC = "p63" ; #pin 10
NET "kb_clock" LOC = "p64" ; #pin 11
NET "kb_data" LOC = "p68" ; #pin 12
#NET "mouse-clock" LOC = "p69" ; #pin 13
#NET "mouse_data" LOC = "p70" ; #pin 14
#NET "buzzer" LOC = "p71" ; #pin 15
NET "cts_n" LOC = "p73" ; #pin 16
NET "rxbit" LOC = "p74" ; #pin 17
NET "txbit" LOC = "p75" ; #pin 18
NET "rts_n" LOC = "p81" ; #pin 19
#
# For B3-FPGA-CPU-IO
# I/O Port
# Connector D
#
#NET "aux_clock" LOC = "p80" ; #pin 2
#NET "buzzer" LOC = "p82" ; #pin 3
NET "led" LOC = "p82" ; #pin 3
#NET "mouse_clock" LOC = "p83" ; #pin 4
#NET "mouse_data" LOC = "p84" ; #pin 5
NET "cts_n" LOC = "p86" ; #pin 6
NET "rts_n" LOC = "p87" ; #pin 7
NET "txbit" LOC = "p88" ; #pin 8
NET "rxbit" LOC = "p89" ; #pin 9
#NET "kb_clock" LOC = "p93" ; #pin 10
#NET "kb_data" LOC = "p94" ; #pin 11
#NET "v_drive" LOC = "p95" ; #pin 12
#NET "h_drive" LOC = "p96" ; #pin 13
#NET "blue_lo" LOC = "p97" ; #pin 14
#NET "blue_hi" LOC = "p98" ; #pin 15
#NET "green_lo" LOC = "p99" ; #pin 16
#NET "green_hi" LOC = "p100"; #pin 17
#NET "red_lo" LOC = "p101"; #pin 18
#NET "red_hi" LOC = "p102"; #pin 19
#NET "pin2clk" LOC = "p80" ; #pin 2 (Clock input)
NET "led" LOC = "p82" ; #pin 3
NET "porta<0>" LOC = "p83" ; #pin 4
NET "porta<1>" LOC = "p84" ; #pin 5
NET "porta<2>" LOC = "p86" ; #pin 6
NET "porta<3>" LOC = "p87" ; #pin 7
NET "porta<4>" LOC = "p88" ; #pin 8
NET "porta<5>" LOC = "p89" ; #pin 9
NET "porta<6>" LOC = "p93" ; #pin 10
NET "porta<7>" LOC = "p94" ; #pin 11
NET "portb<0>" LOC = "p95" ; #pin 12
NET "portb<1>" LOC = "p96" ; #pin 13
NET "portb<2>" LOC = "p97" ; #pin 14
NET "portb<3>" LOC = "p98" ; #pin 15
NET "portb<4>" LOC = "p99" ; #pin 16
NET "portb<5>" LOC = "p100"; #pin 17
NET "portb<6>" LOC = "p101"; #pin 18
NET "portb<7>" LOC = "p102"; #pin 19
#
# For modified B3-SRAM
# For B5-SRAM
# Connector E
#
NET "ram_addr<0>" LOC = "p108"; #J1.2
NET "ram_addr<1>" LOC = "p109"; #J1.3
NET "ram_addr<2>" LOC = "p110"; #J1.4
NET "ram_addr<3>" LOC = "p111"; #J1.5
NET "ram_addr<4>" LOC = "p112"; #J1.6
NET "ram_addr<5>" LOC = "p113"; #J1.7
NET "ram_addr<6>" LOC = "p114"; #J1.8
NET "ram_addr<7>" LOC = "p115"; #J1.9
NET "ram_csn" LOC = "p116"; #J1.10
NET "ram_csn" LOC = "p108"; #J1.2
NET "ram_addr<16>" LOC = "p109"; #J1.3
NET "ram_addr<15>" LOC = "p110"; #J1.4
NET "ram_addr<14>" LOC = "p111"; #J1.5
NET "ram_addr<13>" LOC = "p112"; #J1.6
NET "ram_addr<12>" LOC = "p113"; #J1.7
NET "ram_addr<11>" LOC = "p114"; #J1.8
NET "ram_addr<10>" LOC = "p115"; #J1.9
NET "ram_addr<9>" LOC = "p116"; #J1.10
NET "ram_addr<8>" LOC = "p120"; #J1.11
NET "ram_addr<9>" LOC = "p121"; #J1.12
NET "ram_addr<10>" LOC = "p122"; #J1.13
NET "ram_addr<11>" LOC = "p123"; #J1.14
NET "ram_addr<12>" LOC = "p125"; #J1.15
NET "ram_addr<13>" LOC = "p126"; #J1.16
NET "ram_addr<14>" LOC = "p127"; #J1.17
NET "ram_addr<15>" LOC = "p129"; #J1.18
NET "ram_addr<16>" LOC = "p132"; #J1.19
NET "ram_addr<7>" LOC = "p121"; #J1.12
NET "ram_addr<6>" LOC = "p122"; #J1.13
NET "ram_addr<5>" LOC = "p123"; #J1.14
NET "ram_addr<4>" LOC = "p125"; #J1.15
NET "ram_addr<3>" LOC = "p126"; #J1.16
NET "ram_addr<2>" LOC = "p127"; #J1.17
NET "ram_addr<1>" LOC = "p129"; #J1.18
NET "ram_addr<0>" LOC = "p132"; #J1.19
#
# For modified B3-SRAM
# For B5-SRAM
# Connector F
#
NET "ram_data<0>" LOC = "p133"; #J2.2
NET "ram_data<1>" LOC = "p134"; #J2.3
NET "ram_data<2>" LOC = "p135"; #J2.4
NET "ram_data<3>" LOC = "p136"; #J2.5
NET "ram_data<4>" LOC = "p138"; #J2.6
NET "ram_data<5>" LOC = "p139"; #J2.7
NET "ram_data<6>" LOC = "p140"; #J2.8
NET "ram_data<7>" LOC = "p141"; #J2.9
NET "ram_data<8>" LOC = "p145"; #J2.10
NET "ram_data<9>" LOC = "p146"; #J2.11
NET "ram_data<10>" LOC = "p147"; #J2.12
NET "ram_data<11>" LOC = "p148"; #J2.13
NET "ram_data<12>" LOC = "p149"; #J2.14
NET "ram_data<13>" LOC = "p150"; #J2.15
NET "ram_data<14>" LOC = "p151"; #J2.16
NET "ram_data<15>" LOC = "p152"; #J2.17
NET "ram_wrun" LOC = "p153"; #J2.18
NET "ram_wrln" LOC = "p154"; #J2.19
NET "ram_wrun" LOC = "p133"; #J2.2
NET "ram_wrln" LOC = "p134"; #J2.3
NET "ram_data<15>" LOC = "p135"; #J2.4
NET "ram_data<14>" LOC = "p136"; #J2.5
NET "ram_data<13>" LOC = "p138"; #J2.6
NET "ram_data<12>" LOC = "p139"; #J2.7
NET "ram_data<11>" LOC = "p140"; #J2.8
NET "ram_data<10>" LOC = "p141"; #J2.9
NET "ram_data<9>" LOC = "p145"; #J2.10
NET "ram_data<8>" LOC = "p146"; #J2.11
NET "ram_data<7>" LOC = "p147"; #J2.12
NET "ram_data<6>" LOC = "p148"; #J2.13
NET "ram_data<5>" LOC = "p149"; #J2.14
NET "ram_data<4>" LOC = "p150"; #J2.15
NET "ram_data<3>" LOC = "p151"; #J2.16
NET "ram_data<2>" LOC = "p152"; #J2.17
NET "ram_data<1>" LOC = "p153"; #J2.18
NET "ram_data<0>" LOC = "p154"; #J2.19
#
# Connector G
#
#NET "pin2" LOC = "p182"; #pin 2 (clk input)
NET "test_alu<0>" LOC = "p160"; #pin 3
NET "test_alu<1>" LOC = "p161"; #pin 4
NET "test_alu<2>" LOC = "p162"; #pin 5
NET "test_alu<3>" LOC = "p163"; #pin 6
NET "test_alu<4>" LOC = "p164"; #pin 7
NET "test_alu<5>" LOC = "p165"; #pin 8
NET "test_alu<6>" LOC = "p166"; #pin 9
NET "test_alu<7>" LOC = "p167"; #pin 10
NET "test_alu<8>" LOC = "p168"; #pin 11
NET "test_alu<9>" LOC = "p169"; #pin 12
NET "test_alu<10>" LOC = "p173"; #pin 13
NET "test_alu<11>" LOC = "p174"; #pin 14
NET "test_alu<12>" LOC = "p175"; #pin 15
NET "test_alu<13>" LOC = "p176"; #pin 16
NET "test_alu<14>" LOC = "p178"; #pin 17
NET "test_alu<15>" LOC = "p179"; #pin 18
#NET "pin19" LOC = "p180"; #pin 19
#NET "pin2" LOC = "p182"; #pin 2 (clk input)
NET "bus_addr<0>" LOC = "p160"; #pin 3
NET "bus_addr<1>" LOC = "p161"; #pin 4
NET "bus_addr<2>" LOC = "p162"; #pin 5
NET "bus_addr<3>" LOC = "p163"; #pin 6
NET "bus_addr<4>" LOC = "p164"; #pin 7
NET "bus_addr<5>" LOC = "p165"; #pin 8
NET "bus_addr<6>" LOC = "p166"; #pin 9
NET "bus_addr<7>" LOC = "p167"; #pin 10
NET "bus_addr<8>" LOC = "p168"; #pin 11
NET "bus_addr<9>" LOC = "p169"; #pin 12
NET "bus_addr<10>" LOC = "p173"; #pin 13
NET "bus_addr<11>" LOC = "p174"; #pin 14
NET "bus_addr<12>" LOC = "p175"; #pin 15
NET "bus_addr<13>" LOC = "p176"; #pin 16
NET "bus_addr<14>" LOC = "p178"; #pin 17
NET "bus_addr<15>" LOC = "p179"; #pin 18
NET "bus_cs" LOC = "p180"; #pin 19
#
# Connector H
#
#NET "pin2" LOC = "p185"; #pin 2 (clk input)
#NET "pin3" LOC = "p181"; #pin 3
#NET "uart_csn" LOC = "p187"; #pin 4
#NET "test_rw" LOC = "p188"; #pin 5
#NET "test_d0" LOC = "p189"; #pin 6
#NET "test_d1" LOC = "p191"; #pin 7
NET "bus_clk" LOC = "p181"; #pin 3
NET "bus_reset" LOC = "p187"; #pin 4
#NET "pin5" LOC = "p188"; #pin 5
#NET "pin6" LOC = "p189"; #pin 6
#NET "pin7" LOC = "p191"; #pin 7
#NET "pin8" LOC = "p192"; #pin 8
#NET "pin9" LOC = "p193"; #pin 9
#NET "pin10" LOC = "p194"; #pin 10
NET "test_cc<0>" LOC = "p198"; #pin 11
NET "test_cc<1>" LOC = "p199"; #pin 12
NET "test_cc<2>" LOC = "p200"; #pin 13
NET "test_cc<3>" LOC = "p201"; #pin 14
NET "test_cc<4>" LOC = "p202"; #pin 15
NET "test_cc<5>" LOC = "p203"; #pin 16
NET "test_cc<6>" LOC = "p204"; #pin 17
NET "test_cc<7>" LOC = "p205"; #pin 18
#NET "pin19" LOC = "p206"; #pin 19
NET "timer_out" LOC = "p194"; #pin 10
NET "bus_data<0>" LOC = "p198"; #pin 11
NET "bus_data<1>" LOC = "p199"; #pin 12
NET "bus_data<2>" LOC = "p200"; #pin 13
NET "bus_data<3>" LOC = "p201"; #pin 14
NET "bus_data<4>" LOC = "p202"; #pin 15
NET "bus_data<5>" LOC = "p203"; #pin 16
NET "bus_data<6>" LOC = "p204"; #pin 17
NET "bus_data<7>" LOC = "p205"; #pin 18
NET "bus_rw" LOC = "p206"; #pin 19
#
# Timing Groups
#
INST "ram_addr<0>" TNM = "ram_addr";
INST "ram_addr<1>" TNM = "ram_addr";
INST "ram_addr<2>" TNM = "ram_addr";
INST "ram_addr<3>" TNM = "ram_addr";
INST "ram_addr<4>" TNM = "ram_addr";
INST "ram_addr<5>" TNM = "ram_addr";
INST "ram_addr<6>" TNM = "ram_addr";
INST "ram_addr<7>" TNM = "ram_addr";
INST "ram_addr<8>" TNM = "ram_addr";
INST "ram_addr<9>" TNM = "ram_addr";
INST "ram_addr<10>" TNM = "ram_addr";
INST "ram_addr<11>" TNM = "ram_addr";
INST "ram_addr<12>" TNM = "ram_addr";
INST "ram_addr<13>" TNM = "ram_addr";
INST "ram_addr<14>" TNM = "ram_addr";
INST "ram_addr<15>" TNM = "ram_addr";
INST "ram_addr<16>" TNM = "ram_addr";
INST "ram_data<0>" TNM = "ram_data";
INST "ram_data<1>" TNM = "ram_data";
INST "ram_data<2>" TNM = "ram_data";
INST "ram_data<3>" TNM = "ram_data";
INST "ram_data<4>" TNM = "ram_data";
INST "ram_data<5>" TNM = "ram_data";
INST "ram_data<6>" TNM = "ram_data";
INST "ram_data<7>" TNM = "ram_data";
INST "ram_data<8>" TNM = "ram_data";
INST "ram_data<9>" TNM = "ram_data";
INST "ram_data<10>" TNM = "ram_data";
INST "ram_data<11>" TNM = "ram_data";
INST "ram_data<12>" TNM = "ram_data";
INST "ram_data<13>" TNM = "ram_data";
INST "ram_data<14>" TNM = "ram_data";
INST "ram_data<15>" TNM = "ram_data";
INST "ram_wrln" TNM = "ram_wr";
INST "ram_wrun" TNM = "ram_wr";
INST "ram_csn" TNM = "ram_cs";
INST "test_alu<0>" TNM = "test_alu";
INST "test_alu<1>" TNM = "test_alu";
INST "test_alu<2>" TNM = "test_alu";
INST "test_alu<3>" TNM = "test_alu";
INST "test_alu<4>" TNM = "test_alu";
INST "test_alu<5>" TNM = "test_alu";
INST "test_alu<6>" TNM = "test_alu";
INST "test_alu<7>" TNM = "test_alu";
INST "test_alu<8>" TNM = "test_alu";
INST "test_alu<9>" TNM = "test_alu";
INST "test_alu<10>" TNM = "test_alu";
INST "test_alu<11>" TNM = "test_alu";
INST "test_alu<12>" TNM = "test_alu";
INST "test_alu<13>" TNM = "test_alu";
INST "test_alu<14>" TNM = "test_alu";
INST "test_alu<15>" TNM = "test_alu";
INST "test_cc<0>" TNM = "test_cc";
INST "test_cc<1>" TNM = "test_cc";
INST "test_cc<2>" TNM = "test_cc";
INST "test_cc<3>" TNM = "test_cc";
INST "test_cc<4>" TNM = "test_cc";
INST "test_cc<5>" TNM = "test_cc";
INST "test_cc<6>" TNM = "test_cc";
INST "test_cc<7>" TNM = "test_cc";
INST "ram_addr<0>" TNM = "gram_addr";
INST "ram_addr<1>" TNM = "gram_addr";
INST "ram_addr<2>" TNM = "gram_addr";
INST "ram_addr<3>" TNM = "gram_addr";
INST "ram_addr<4>" TNM = "gram_addr";
INST "ram_addr<5>" TNM = "gram_addr";
INST "ram_addr<6>" TNM = "gram_addr";
INST "ram_addr<7>" TNM = "gram_addr";
INST "ram_addr<8>" TNM = "gram_addr";
INST "ram_addr<9>" TNM = "gram_addr";
INST "ram_addr<10>" TNM = "gram_addr";
INST "ram_addr<11>" TNM = "gram_addr";
INST "ram_addr<12>" TNM = "gram_addr";
INST "ram_addr<13>" TNM = "gram_addr";
INST "ram_addr<14>" TNM = "gram_addr";
INST "ram_addr<15>" TNM = "gram_addr";
INST "ram_addr<16>" TNM = "gram_addr";
INST "ram_data<0>" TNM = "gram_data";
INST "ram_data<1>" TNM = "gram_data";
INST "ram_data<2>" TNM = "gram_data";
INST "ram_data<3>" TNM = "gram_data";
INST "ram_data<4>" TNM = "gram_data";
INST "ram_data<5>" TNM = "gram_data";
INST "ram_data<6>" TNM = "gram_data";
INST "ram_data<7>" TNM = "gram_data";
INST "ram_data<8>" TNM = "gram_data";
INST "ram_data<9>" TNM = "gram_data";
INST "ram_data<10>" TNM = "gram_data";
INST "ram_data<11>" TNM = "gram_data";
INST "ram_data<12>" TNM = "gram_data";
INST "ram_data<13>" TNM = "gram_data";
INST "ram_data<14>" TNM = "gram_data";
INST "ram_data<15>" TNM = "gram_data";
INST "ram_wrln" TNM = "gram_wr";
INST "ram_wrun" TNM = "gram_wr";
INST "ram_csn" TNM = "gram_cs";
#
# Timing Constraints
#
TIMEGRP "ram_cs" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_wr" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_addr" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_data" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_data" OFFSET = IN 15 ns BEFORE "sysclk";
TIMEGRP "test_alu" OFFSET = OUT 90 ns AFTER "sysclk";
TIMEGRP "test_cc" OFFSET = OUT 95 ns AFTER "sysclk";
#TIMEGRP "gram_cs" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_wr" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_addr" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_data" OFFSET = OUT 40 ns AFTER "sysclk";
#TIMEGRP "gram_data" OFFSET = IN 15 ns BEFORE "sysclk";
#TIMEGRP "gtest_alu" OFFSET = OUT 90 ns AFTER "sysclk";
#TIMEGRP "gtest_cc" OFFSET = OUT 95 ns AFTER "sysclk";
NET "sysclk" TNM_NET = "sysclk";
TIMESPEC "TS_sysclk" = PERIOD "sysclk" 100 ns LOW 50 %;
#
# Fast I/O Pins
#
NET "ram_addr<0>" FAST;
NET "ram_addr<1>" FAST;
NET "ram_addr<2>" FAST;
NET "ram_addr<3>" FAST;
NET "ram_addr<4>" FAST;
NET "ram_addr<5>" FAST;
NET "ram_addr<6>" FAST;
NET "ram_addr<7>" FAST;
NET "ram_addr<8>" FAST;
NET "ram_addr<9>" FAST;
NET "ram_addr<10>" FAST;
NET "ram_addr<11>" FAST;
NET "ram_addr<12>" FAST;
NET "ram_addr<13>" FAST;
NET "ram_addr<14>" FAST;
NET "ram_addr<15>" FAST;
NET "ram_addr<16>" FAST;
NET "ram_csn" FAST;
NET "ram_data<0>" FAST;
NET "ram_data<1>" FAST;
NET "ram_data<2>" FAST;
NET "ram_data<3>" FAST;
NET "ram_data<4>" FAST;
NET "ram_data<5>" FAST;
NET "ram_data<6>" FAST;
NET "ram_data<7>" FAST;
NET "ram_data<8>" FAST;
NET "ram_data<9>" FAST;
NET "ram_data<10>" FAST;
NET "ram_data<11>" FAST;
NET "ram_data<12>" FAST;
NET "ram_data<13>" FAST;
NET "ram_data<14>" FAST;
NET "ram_data<15>" FAST;
NET "ram_wrln" FAST;
NET "ram_wrun" FAST;
/trunk/rtl/vhdl/blockram.vhd
0,0 → 1,211
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
entity block_ram is
Port (
MEMclk : in std_logic;
MEMcs : in std_logic;
MEMrw : in std_logic;
MEMaddr : in std_logic_vector (10 downto 0);
MEMrdata : out std_logic_vector (7 downto 0);
MEMwdata : in std_logic_vector (7 downto 0)
);
end block_ram;
 
architecture rtl of block_ram is
 
signal dout0 : std_logic_vector (7 downto 0);
signal dout1 : std_logic_vector (7 downto 0);
signal dout2 : std_logic_vector (7 downto 0);
signal dout3 : std_logic_vector (7 downto 0);
 
signal ena0 : std_logic;
signal ena1 : std_logic;
signal ena2 : std_logic;
signal ena3 : std_logic;
 
signal we : std_logic;
 
component RAMB4_S8
generic (
INIT_00, INIT_01, INIT_02, INIT_03,
INIT_04, INIT_05, INIT_06, INIT_07,
INIT_08, INIT_09, INIT_0A, INIT_0B,
INIT_0C, INIT_0D, INIT_0E, INIT_0F : bit_vector (255 downto 0)
);
 
port (
clk, we, en, rst : in std_logic;
addr : in std_logic_vector(8 downto 0);
di : in std_logic_vector(7 downto 0);
do : out std_logic_vector(7 downto 0)
);
end component RAMB4_S8;
 
begin
 
RAM0 : RAMB4_S8
generic map (
INIT_00 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_01 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => x"0000000000000000000000000000000000000000000000000000000000000000"
)
 
port map ( clk => MEMclk,
en => ena0,
we => we,
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout0(7 downto 0)
);
 
RAM1 : RAMB4_S8
generic map (
INIT_00 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_01 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => x"0000000000000000000000000000000000000000000000000000000000000000"
)
 
port map ( clk => MEMclk,
en => ena1,
we => we,
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout1(7 downto 0)
);
 
RAM2 : RAMB4_S8
generic map (
INIT_00 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_01 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => x"0000000000000000000000000000000000000000000000000000000000000000"
)
port map ( clk => MEMclk,
en => ena2,
we => we,
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout2(7 downto 0)
);
 
RAM3 : RAMB4_S8
generic map (
INIT_00 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_01 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => x"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => x"0000000000000000000000000000000000000000000000000000000000000000"
)
port map ( clk => MEMclk,
en => ena3,
we => we,
rst => '0',
addr(8 downto 0) => MEMaddr(8 downto 0),
di(7 downto 0) => MEMwdata,
do(7 downto 0) => dout3(7 downto 0)
);
 
my_ram : process ( MEMaddr, MEMrw, MEMcs, dout0, dout1, dout2, dout3 )
begin
case MEMaddr(10 downto 9) is
when "00" =>
ena0 <= '1';
ena1 <= '0';
ena2 <= '0';
ena3 <= '0';
when "01" =>
ena0 <= '0';
ena1 <= '1';
ena2 <= '0';
ena3 <= '0';
when "10" =>
ena0 <= '0';
ena1 <= '0';
ena2 <= '1';
ena3 <= '0';
when "11" =>
ena0 <= '0';
ena1 <= '0';
ena2 <= '0';
ena3 <= '1';
when others =>
ena0 <= '0';
ena1 <= '0';
ena2 <= '0';
ena3 <= '0';
end case;
 
case MEMaddr(10 downto 9) is
when "00" =>
MEMrdata <= dout0;
when "01" =>
MEMrdata <= dout1;
when "10" =>
MEMrdata <= dout2;
when "11" =>
MEMrdata <= dout3;
when others =>
MEMrdata <= x"00";
end case;
 
we <= MEMcs and (not MEMrw);
 
end process my_ram;
 
end architecture rtl;
 
/trunk/rtl/vhdl/charrom.vhd
0,0 → 1,127
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library unisim;
use unisim.all;
--library simprim;
-- use simprim.all;
 
entity char_rom is
Port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector (9 downto 0);
wdata : in std_logic_vector (7 downto 0);
rdata : out std_logic_vector (7 downto 0)
);
end char_rom;
 
architecture rtl of char_rom is
 
signal we : std_logic;
signal reset : std_logic;
signal rdata0 : std_logic_vector (7 downto 0);
signal rdata1 : std_logic_vector (7 downto 0);
signal ena0 : std_logic;
signal ena1 : std_logic;
 
component RAMB4_S8
generic (
INIT_00, INIT_01, INIT_02, INIT_03,
INIT_04, INIT_05, INIT_06, INIT_07,
INIT_08, INIT_09, INIT_0A, INIT_0B,
INIT_0C, INIT_0D, INIT_0E, INIT_0F : bit_vector (255 downto 0) :=
x"0000000000000000000000000000000000000000000000000000000000000000"
);
 
port (
clk, we, en, rst : in std_logic;
addr : in std_logic_vector(8 downto 0);
di : in std_logic_vector(7 downto 0);
do : out std_logic_vector(7 downto 0)
);
end component;
 
begin
 
CH_ROM0 : RAMB4_S8
generic map (
INIT_00 => x"000000FF0000001010101010101010003E1C7F7F3E1C08000000FF0000000000",
INIT_01 => x"202020202020200000FF0000000000000000000000FF000000000000FF000000",
INIT_02 => x"0000E0100808080000000304080808080810E000000000040404040404040420",
INIT_03 => x"808080808080FF80402010080402010102040810204080FF8080808080808000",
INIT_04 => x"081C3E7F7F7F3600FF000000000000003C7E7E7E7E3C0001010101010101FF80",
INIT_05 => x"3C424242423C0081422418182442810808040300000000404040404040404000",
INIT_06 => x"0808FF0808080800081C3E7F3E1C0802020202020202020008082A772A1C0800",
INIT_07 => x"03070F1F3F7FFF001414543E010000080808080808080850A050A050A050A008",
INIT_08 => x"24247E247E242400000000002424240008000008080808000000000000000000",
INIT_09 => x"00000000100804003A444A30484830004626100864620000083C0A1C281E0800",
INIT_0A => x"0008083E08080000082A1C3E1C2A080020100808081020000408101010080400",
INIT_0B => x"402010080402000018180000000000000000007E000000100808000000000000",
INIT_0C => x"3C42021C02423C007E40300C02423C003E080808281808003C42625A46423C00",
INIT_0D => x"1010100804427E003C42427C40201C003844020478407E0004047E24140C0400",
INIT_0E => x"080800000800000000080000080000003804023E42423C003C42423C42423C00",
INIT_0F => x"1000100C02423C0070180C060C18700000007E007E0000000E18306030180E10"
)
 
port map ( clk => clk,
en => ena0,
we => we,
rst => reset,
addr(8 downto 0) => addr(8 downto 0),
di(7 downto 0) => wdata(7 downto 0),
do(7 downto 0) => rdata0(7 downto 0)
);
 
CH_ROM1 : RAMB4_S8
generic map (
 
INIT_00 => x"001C22404040221C007C22223C22227C004242427E422418001E204C564A221C",
INIT_01 => x"001C22424E40221C004040407840407E007E40407840407E0078242222222478",
INIT_02 => x"0042444870484442003844040404040E001C08080808081C004242427E424242",
INIT_03 => x"0018244242422418004242464A526242004242425A5A6642007E404040404040",
INIT_04 => x"003C42023C40423C004244487C42427C001A244A42422418004040407C42427C",
INIT_05 => x"0042665A5A4242420018182424424242003C424242424242000808080808083E",
INIT_06 => x"003C20202020203C007E40201804027E000808081C2222220042422418244242",
INIT_07 => x"0010207F20100000080808082A1C0800003C04040404043C006E70103C10100C",
INIT_08 => x"003C4240423C0000005C6242625C4040003A443C04380000001E204C564A221C",
INIT_09 => x"3C023A46463A0000001010107C10120C003C407E423C0000003A4642463A0202",
INIT_0A => x"004468504844404038440404040C0004001C08080818000800424242625C4040",
INIT_0B => x"003C4242423C000000424242625C00000049494949760000001C080808080818",
INIT_0C => x"007C023C403E000000404040625C000002023A46463A000040405C62625C0000",
INIT_0D => x"00364949494100000018244242420000003A464242420000000C1210107C1010",
INIT_0E => x"003C20202020203C007E2018047E00003C023A46424200000042241824420000",
INIT_0F => x"0010207F20100000080808082A1C0800003C04040404043C006E70103C10100C"
)
 
port map ( clk => clk,
en => ena1,
we => we,
rst => reset,
addr(8 downto 0) => addr(8 downto 0),
di(7 downto 0) => wdata(7 downto 0),
do(7 downto 0) => rdata1(7 downto 0)
);
 
my_chargen : process ( clk, rst, cs, rw, rdata0, rdata1 )
begin
if addr(9) = '0' then
ena0 <= cs;
ena1 <= '0';
rdata <= rdata0;
else
ena0 <= '0';
ena1 <= cs;
rdata <= rdata1;
end if;
 
we <= cs and (not rw);
reset <= '0';
 
end process;
 
end;
 
/trunk/rtl/vhdl/System09.vhd
10,7 → 10,7
-- Purpose : Top level file for 6809 compatible system on a chip
-- Designed with Xilinx XC2S300e Spartan 2+ FPGA.
-- Implemented With BurchED B5-X300 FPGA board,
-- B3-SRAM module, B5-CF module and B3-FPGA-CPU-IO module
-- B5-SRAM module, B5-CF module and B5-FPGA-CPU-IO module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
20,10 → 20,9
-- Uses : boot_rom (sbug.vhd) Monitor ROM
-- cpu09 (cpu09.vhd) CPU core
-- dat_ram (datram.vhd) Dynamic Address Translation
-- miniuart (minitUART2.vhd) ACIA / MiniUART
-- (rxunit2.vhd)
-- (tx_unit2.vhd)
-- (clkunit2.vhd)
-- miniuart (minitUART3.vhd) ACIA / MiniUART
-- (rxunit3.vhd)
-- (tx_unit3.vhd)
-- timer (timer.vhd) Timer module
--
-- Author : John E. Kent
37,14 → 36,30
-- Version 0.2 - 30 March 2003
-- Version 0.3 - 29 April 2003
-- Version 0.4 - 29 June 2003
--
-- Version 0.5 - 19 July 2003
-- prints out "Hello World"
--
-- Version 0.6 - 5 September 2003
-- Runs SBUG
--
-- Version 1.0- 6 Sep 2003 - John Kent
-- Inverted SysClk
-- Initial release to Open Cores
--
-- Version 1.1 - 17 Jan 2004 - John Kent
-- Updated miniUart.
--
-- Version 1.2 - 25 Jan 2004 - John Kent
-- removed signals "test_alu" and "test_cc"
-- Trap hardware re-instated.
--
-- Version 1.3 - 11 Feb 2004 - John Kent
-- Designed forked off to produce System09_VDU
-- Added VDU component
-- VDU runs at 25MHz and divides the clock by 2 for the CPU
-- UART Runs at 57.6 Kbps
--
--===========================================================================--
library ieee;
use ieee.std_logic_1164.all;
52,7 → 67,7
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity System09 is
entity My_System09 is
port(
SysClk : in Std_Logic; -- System Clock input
Reset_n : in Std_logic; -- Master Reset input (active low)
66,8 → 81,11
ram_data : inout Std_Logic_Vector(15 downto 0);
 
-- Stuff on the peripheral board
-- aux_clock : in Std_Logic; -- FPGA-CPU-IO clock
 
-- PS/2 Keyboard
kb_clock : inout Std_logic;
kb_data : inout Std_Logic;
 
-- PS/2 Mouse interface
-- mouse_clock : in Std_Logic;
-- mouse_data : in Std_Logic;
79,14 → 97,14
cts_n : in Std_Logic;
 
-- CRTC output signals
-- v_drive : out Std_Logic;
-- h_drive : out Std_Logic;
-- blue_lo : out std_logic;
-- blue_hi : out std_logic;
-- green_lo : out std_logic;
-- green_hi : out std_logic;
-- red_lo : out std_logic;
-- red_hi : out std_logic;
v_drive : out Std_Logic;
h_drive : out Std_Logic;
blue_lo : out std_logic;
blue_hi : out std_logic;
green_lo : out std_logic;
green_hi : out std_logic;
red_lo : out std_logic;
red_hi : out std_logic;
-- buzzer : out std_logic;
 
-- Compact Flash
100,20 → 118,26
cf_d : inout std_logic_vector(15 downto 0);
 
-- Parallel I/O port
-- porta : inout std_logic_vector(7 downto 0);
-- portb : inout std_logic_vector(7 downto 0);
-- timer_out : out std_logic;
porta : inout std_logic_vector(7 downto 0);
portb : inout std_logic_vector(7 downto 0);
 
-- Test Pins
test_alu : out std_logic_vector(15 downto 0);
test_cc : out std_logic_vector(7 downto 0)
-- CPU bus
bus_clk : out std_logic;
bus_reset : out std_logic;
bus_rw : out std_logic;
bus_cs : out std_logic;
bus_addr : out std_logic_vector(15 downto 0);
bus_data : inout std_logic_vector(7 downto 0);
 
-- timer
timer_out : out std_logic
);
end System09;
end My_System09;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-- Architecture for System09
-------------------------------------------------------------------------------
architecture my_computer of System09 is
architecture my_computer of My_System09 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
124,15 → 148,22
signal uart_data_out : Std_Logic_Vector(7 downto 0);
signal uart_cs : Std_Logic;
signal uart_irq : Std_Logic;
signal baudclk : Std_Logic;
signal DCD_n : Std_Logic;
 
-- timer
-- signal timer_data_out : std_logic_vector(7 downto 0);
-- signal timer_cs : std_logic;
-- signal timer_irq : std_logic;
signal timer_data_out : std_logic_vector(7 downto 0);
signal timer_cs : std_logic;
signal timer_irq : std_logic;
 
-- trap
signal trap_cs : std_logic;
signal trap_data_out : std_logic_vector(7 downto 0);
signal trap_irq : std_logic;
 
-- Parallel I/O port
-- signal ioport_data_out : std_logic_vector(7 downto 0);
-- signal ioport_cs : std_logic;
signal ioport_data_out : std_logic_vector(7 downto 0);
signal ioport_cs : std_logic;
 
-- compact flash port
signal cf_data_out : std_logic_vector(7 downto 0);
140,6 → 171,11
signal cf_rd : std_logic;
signal cf_wr : std_logic;
 
-- keyboard port
signal keyboard_data_out : std_logic_vector(7 downto 0);
signal keyboard_cs : std_logic;
signal keyboard_irq : std_logic;
 
-- RAM
signal ram_cs : std_logic; -- memory chip select
signal ram_wrl : std_logic; -- memory write lower
147,33 → 183,30
signal ram_data_out : std_logic_vector(7 downto 0);
 
-- CPU Interface signals
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_halt : std_logic;
signal cpu_hold : std_logic;
signal cpu_firq : std_logic;
signal cpu_irq : std_logic;
signal cpu_nmi : std_logic;
signal cpu_addr : std_logic_vector(15 downto 0);
signal cpu_data_in : std_logic_vector(7 downto 0);
signal cpu_data_out: std_logic_vector(7 downto 0);
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_halt : std_logic;
signal cpu_hold : std_logic;
signal cpu_firq : std_logic;
signal cpu_irq : std_logic;
signal cpu_nmi : std_logic;
signal cpu_addr : std_logic_vector(15 downto 0);
signal cpu_data_in : std_logic_vector(7 downto 0);
signal cpu_data_out : std_logic_vector(7 downto 0);
 
-- Dynamic address translation
signal dat_cs : std_logic;
signal dat_addr : std_logic_vector(7 downto 0);
signal dat_cs : std_logic;
signal dat_addr : std_logic_vector(7 downto 0);
 
-- Boot ROM Map switch
-- signal map_cs : Std_Logic;
-- signal map_sw : Std_Logic;
-- Video Display Unit
signal vdu_cs : std_logic;
signal vdu_data_out : std_logic_vector(7 downto 0);
 
-- synchronous RAM
-- signal xram_data_out : std_logic_vector(7 downto 0);
-- signal xram_cs : std_logic;
 
-- Flashing Led test signals
signal countL : std_logic_vector(23 downto 0);
signal BaudCount : std_logic_vector(4 downto 0);
 
-----------------------------------------------------------------
--
194,12 → 227,52
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
firq: in std_logic
);
end component;
 
----------------------------------------
--
-- SBUG Slice Monitor ROM
--
----------------------------------------
--component boot_rom
-- port (
-- addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom
-- data : out Std_Logic_Vector(7 downto 0));
--end component;
 
----------------------------------------
--
-- SBUG Block RAM Monitor ROM
--
----------------------------------------
component sbug_rom
Port (
MEMclk : in std_logic;
MEMaddr : in std_logic_vector (10 downto 0);
MEMrdata : out std_logic_vector (7 downto 0)
);
end component;
 
----------------------------------------
--
-- Dynamic Address Translation Registers
--
----------------------------------------
component dat_ram
port (
clk: in std_logic;
rst: in std_logic;
cs: in std_logic;
rw: in std_logic;
addr_lo: in std_logic_vector(3 downto 0);
addr_hi: in std_logic_vector(3 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0)
);
end component;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
208,20 → 281,24
 
component miniUART
port (
SysClk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input
cs : in Std_Logic;
rw : in Std_Logic;
RxD : in Std_Logic;
TxD : out Std_Logic;
CTS_n : in Std_Logic;
RTS_n : out Std_Logic;
Irq : out Std_logic;
Addr : in Std_Logic;
DataIn : in Std_Logic_Vector(7 downto 0); --
DataOut : out Std_Logic_Vector(7 downto 0)); --
clk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic; -- miniUART Chip Select
rw : in Std_Logic; -- Read / Not Write
irq : out Std_Logic; -- Interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In
DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
RxC : in Std_Logic; -- Receive Baud Clock
TxC : in Std_Logic; -- Transmit Baud Clock
RxD : in Std_Logic; -- Receive Data
TxD : out Std_Logic; -- Transmit Data
DCD_n : in Std_Logic; -- Data Carrier Detect
CTS_n : in Std_Logic; -- Clear To Send
RTS_n : out Std_Logic ); -- Request To send
end component;
 
 
----------------------------------------
--
-- Timer module
228,101 → 305,112
--
----------------------------------------
 
--component timer
-- port (
-- clk : in std_logic;
-- rst : in std_logic;
-- cs : in std_logic;
-- rw : in std_logic;
-- addr : in std_logic;
-- data_in : in std_logic_vector(7 downto 0);
-- data_out : out std_logic_vector(7 downto 0);
-- irq : out std_logic;
-- timer_in : in std_logic;
-- timer_out : out std_logic
-- );
--end component;
component timer
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic;
timer_in : in std_logic;
timer_out : out std_logic
);
end component;
 
----------------------------------------
------------------------------------------------------------
--
-- Dual 8 bit Parallel I/O module
-- Bus Trap logic
--
----------------------------------------
--component ioport
-- port (
-- clk : in std_logic;
-- rst : in std_logic;
-- cs : in std_logic;
-- rw : in std_logic;
-- addr : in std_logic_vector(1 downto 0);
-- data_in : in std_logic_vector(7 downto 0);
-- data_out : out std_logic_vector(7 downto 0);
-- porta_io : inout std_logic_vector(7 downto 0);
-- portb_io : inout std_logic_vector(7 downto 0)
-- );
--end component;
------------------------------------------------------------
 
component trap
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
vma : in std_logic;
addr : in std_logic_vector(15 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic
);
end component;
 
----------------------------------------
--
-- SBUG Slice Monitor ROM
-- Dual 8 bit Parallel I/O module
--
----------------------------------------
component boot_rom
port (
addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom
data : out Std_Logic_Vector(7 downto 0));
component ioport
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(1 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
porta_io : inout std_logic_vector(7 downto 0);
portb_io : inout std_logic_vector(7 downto 0)
);
end component;
 
----------------------------------------
--
-- SBUG Block RAM Monitor ROM
-- PS/2 Keyboard
--
----------------------------------------
--component sbug_rom
-- Port (
-- MEMclk : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0)
-- );
--end component;
 
----------------------------------------
--
-- Dynamic Address Translation Registers
--
----------------------------------------
component dat_ram
port (
clk: in std_logic;
rst: in std_logic;
cs: in std_logic;
rw: in std_logic;
addr_lo: in std_logic_vector(3 downto 0);
addr_hi: in std_logic_vector(3 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0)
);
component keyboard
port(
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic;
kbd_clk : inout std_logic;
kbd_data : inout std_logic
);
end component;
 
----------------------------------------
--
-- Block RAM module
-- Video Display Unit.
--
----------------------------------------
-- component block_ram
-- Port (
-- MEMclk : in std_logic;
-- MEMcs : in std_logic;
-- MEMrw : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0);
-- MEMwdata : in std_logic_vector (7 downto 0)
-- );
--end component;
component vdu
port(
-- control register interface
vdu_clk_in : in std_logic;
vdu_clk_out : out std_logic;
vdu_rst : in std_logic;
vdu_cs : in std_logic;
vdu_rw : in std_logic;
vdu_addr : in std_logic_vector(2 downto 0);
vdu_data_in : in std_logic_vector(7 downto 0);
vdu_data_out : out std_logic_vector(7 downto 0);
 
-- vga port connections
vga_red0_o : out std_logic;
vga_red1_o : out std_logic;
vga_green0_o : out std_logic;
vga_green1_o : out std_logic;
vga_blue0_o : out std_logic;
vga_blue1_o : out std_logic;
vga_hsync_o : out std_logic;
vga_vsync_o : out std_logic
);
end component;
 
-- component BUFG
-- port (
-- port (
-- i: in std_logic;
-- o: out std_logic
-- );
334,7 → 422,7
-----------------------------------------------------------------------------
 
my_cpu : cpu09 port map (
clk => SysClk,
clk => cpu_clk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
345,76 → 433,130
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => test_alu,
test_cc => test_cc
firq => cpu_firq
);
 
--my_rom : boot_rom port map (
-- addr => cpu_addr(10 downto 0),
-- data => rom_data_out
-- );
 
my_rom : sbug_rom port map (
MEMclk => cpu_clk,
MEMaddr => cpu_addr(10 downto 0),
MEMrdata => rom_data_out
);
 
my_dat : dat_ram port map (
clk => cpu_clk,
rst => cpu_reset,
cs => dat_cs,
rw => cpu_rw,
addr_hi => cpu_addr(15 downto 12),
addr_lo => cpu_addr(3 downto 0),
data_in => cpu_data_out,
data_out => dat_addr(7 downto 0)
);
 
my_uart : miniUART port map (
SysClk => SysClk,
clk => cpu_clk,
rst => cpu_reset,
cs => uart_cs,
rw => cpu_rw,
irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out,
RxC => baudclk,
TxC => baudclk,
RxD => rxbit,
TxD => txbit,
DCD_n => dcd_n,
CTS_n => cts_n,
RTS_n => rts_n,
Irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out
RTS_n => rts_n
);
 
--my_timer : timer port map (
-- clk => SysClk,
-- rst => cpu_reset,
-- cs => timer_cs,
-- rw => cpu_rw,
-- addr => cpu_addr(0),
-- data_in => cpu_data_out,
-- data_out => timer_data_out,
-- irq => timer_irq,
-- timer_in => CountL(5),
-- timer_out => timer_out
-- );
my_timer : timer port map (
clk => cpu_clk,
rst => cpu_reset,
cs => timer_cs,
rw => cpu_rw,
addr => cpu_addr(0),
data_in => cpu_data_out,
data_out => timer_data_out,
irq => timer_irq,
timer_in => CountL(5),
timer_out => timer_out
);
 
--my_ioport : ioport port map (
-- clk => SysClk,
-- rst => cpu_reset,
-- cs => ioport_cs,
-- rw => cpu_rw,
-- addr => cpu_addr(1 downto 0),
-- data_in => cpu_data_out,
-- data_out => ioport_data_out,
-- porta_io => porta,
-- portb_io => portb
-- );
my_trap : trap port map (
clk => cpu_clk,
rst => cpu_reset,
cs => trap_cs,
rw => cpu_rw,
vma => cpu_vma,
addr => cpu_addr,
data_in => cpu_data_out,
data_out => trap_data_out,
irq => trap_irq
);
 
my_rom : boot_rom port map (
addr => cpu_addr(10 downto 0),
data => rom_data_out
my_ioport : ioport port map (
clk => cpu_clk,
rst => cpu_reset,
cs => ioport_cs,
rw => cpu_rw,
addr => cpu_addr(1 downto 0),
data_in => cpu_data_out,
data_out => ioport_data_out,
porta_io => porta,
portb_io => portb
);
 
--my_rom : sbug_rom port map (
-- MEMclk => SysClk,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMrdata => rom_data_out
-- );
 
my_dat : dat_ram port map (
clk => SysClk,
rst => cpu_reset,
cs => dat_cs,
rw => cpu_rw,
addr_hi => cpu_addr(15 downto 12),
addr_lo => cpu_addr(3 downto 0),
data_in => cpu_data_out,
data_out => dat_addr(7 downto 0)
);
my_keyboard : keyboard port map(
clk => cpu_clk,
rst => cpu_reset,
cs => keyboard_cs,
rw => cpu_rw,
addr => cpu_addr(0),
data_in => cpu_data_out(7 downto 0),
data_out => keyboard_data_out(7 downto 0),
irq => keyboard_irq,
kbd_clk => kb_clock,
kbd_data => kb_data
);
 
----------------------------------------
--
-- Video Display Unit instantiation
--
----------------------------------------
my_vdu : vdu port map(
 
-- Control Registers
vdu_clk_in => SysClk, -- pixel Clock
vdu_clk_out => cpu_clk, -- memory access clock
vdu_rst => cpu_reset,
vdu_cs => vdu_cs,
vdu_rw => cpu_rw,
vdu_addr => cpu_addr(2 downto 0),
vdu_data_in => cpu_data_out,
vdu_data_out => vdu_data_out,
 
-- vga port connections
vga_red0_o => red_lo,
vga_red1_o => red_hi,
vga_green0_o => green_lo,
vga_green1_o => green_hi,
vga_blue0_o => blue_lo,
vga_blue1_o => blue_hi,
vga_hsync_o => h_drive,
vga_vsync_o => v_drive
);
 
--my_ram : block_ram port map (
-- MEMclk => SysClk,
-- MEMclk => cpu_clk,
-- MEMcs => xram_cs,
-- MEMrw => cpu_rw,
-- MEMaddr => cpu_addr(10 downto 0),
424,7 → 566,7
 
-- clk_buffer : BUFG port map(
-- i => e_clk,
-- o => cpu_clk
-- o => cpu_clk
-- );
----------------------------------------------------------------------
433,14 → 575,14
--
----------------------------------------------------------------------
 
mem_decode: process( SysClk, Reset_n,
mem_decode: process( cpu_clk, Reset_n,
cpu_addr, cpu_rw, cpu_vma,
dat_cs, dat_addr,
-- map_cs, map_sw,
rom_data_out, ram_data_out,
-- xram_data_out,
cf_data_out,
-- timer_data_out, ioport_data_out,
timer_data_out,
trap_data_out,
ioport_data_out,
uart_data_out )
begin
case cpu_addr(15 downto 11) is
449,50 → 591,17
--
when "11111" => -- $F800 - $FFFF
cpu_data_in <= rom_data_out; -- read ROM
dat_cs <= cpu_vma; -- write DAT
ram_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
dat_cs <= cpu_vma; -- write DAT
ram_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= '0';
 
--
-- Shadow RAM Monitor switch
--
-- when "11101" => -- $E800 - $EFFF
-- when "11111" => -- $F800 - $FFFF
-- if map_sw = '1' then
-- cpu_data_in <= rom_data_out; -- read ROM
-- dat_cs <= '0'; -- disable write to DAT
-- ram_cs <= cpu_vma; -- enable write to RAM
-- else
-- cpu_data_in <= ram_data_out; -- read RAM
-- dat_cs <= cpu_vma; -- enable write DAT
-- ram_cs <= cpu_vma and cpu_rw; -- disable write to RAM
-- end if;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= cpu_vma;
-- map_cs <= '0';
 
--
-- Synchronous Block RAM $F000 - $F7FF
--
-- when "11110" => -- $F000 - $F7FF
-- cpu_data_in <= xram_data_out;
-- dat_cs <= '0';
-- ram_cs <= '0';
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= cpu_vma;
-- map_cs <= '0';
 
--
-- IO Devices $E000 - $E7FF
--
499,7 → 608,6
when "11100" => -- $E000 - $E7FF
dat_cs <= '0';
ram_cs <= '0';
-- xram_cs <= '0';
case cpu_addr(7 downto 4) is
--
-- UART / ACIA $E000
508,9 → 616,13
cpu_data_in <= uart_data_out;
uart_cs <= cpu_vma;
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= '0';
 
--
-- Compact Flash $E010 - $E01F
--
518,49 → 630,93
cpu_data_in <= cf_data_out;
uart_cs <= '0';
cf_cs <= cpu_vma;
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= '0';
 
--
-- Timer $E020 - $E02F
--
-- when "0010" => -- $E020
-- cpu_data_in <= timer_data_out;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= cpu_vma;
-- ioport_cs <= '0';
-- map_cs <= '0';
when "0010" => -- $E020
cpu_data_in <= timer_data_out;
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= cpu_vma;
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= '0';
 
--
-- ROM Map switch $E030
-- Bus Trap Logic $E030 - $E03F
--
-- when "0011" => -- $E030
-- cpu_data_in <= "00000000";
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= cpu_vma;
when "0011" => -- $E030
cpu_data_in <= trap_data_out;
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
trap_cs <= cpu_vma;
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= '0';
 
--
-- I/O port $E040 - $E04F
--
-- when "0100" => -- $E040
-- cpu_data_in <= ioport_data_out;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= cpu_vma;
-- map_cs <= '0';
when "0100" => -- $E040
cpu_data_in <= ioport_data_out;
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= cpu_vma;
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= '0';
 
when others => -- $E040 to $E7FF
cpu_data_in <= "00000000";
--
-- Keyboard port $E050 - $E05F
--
when "0101" => -- $E050
cpu_data_in <= keyboard_data_out;
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= cpu_vma;
vdu_cs <= '0';
bus_cs <= '0';
 
--
-- VDU port $E060 - $E06F
--
when "0110" => -- $E060
cpu_data_in <= vdu_data_out;
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= cpu_vma;
bus_cs <= '0';
 
when others => -- $E060 to $E7FF
cpu_data_in <= bus_data;
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= cpu_vma;
end case;
--
-- Everything else is RAM
571,29 → 727,32
dat_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
timer_cs <= '0';
trap_cs <= '0';
ioport_cs <= '0';
keyboard_cs <= '0';
vdu_cs <= '0';
bus_cs <= '0';
end case;
end process;
 
 
--
-- B3-SRAM Control
-- B5-SRAM Control
-- Processes to read and write memory based on bus signals
--
ram_process: process( SysClk, Reset_n,
ram_process: process( cpu_clk, Reset_n,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
dat_addr,
ram_cs, ram_wrl, ram_wru, ram_data_out )
begin
ram_csn <= not( ram_cs and Reset_n );
ram_wrl <= (not dat_addr(5)) and (not cpu_rw) and SysClk;
ram_wrl <= (not cpu_addr(0)) and (not cpu_rw) and cpu_clk;
ram_wrln <= not (ram_wrl);
ram_wru <= dat_addr(5) and (not cpu_rw) and SysClk;
ram_wru <= cpu_addr(0) and (not cpu_rw) and cpu_clk;
ram_wrun <= not (ram_wru);
ram_addr(16 downto 12) <= dat_addr(4 downto 0);
ram_addr(11 downto 0) <= cpu_addr(11 downto 0);
ram_addr(16 downto 11) <= dat_addr(5 downto 0);
ram_addr(10 downto 0) <= cpu_addr(11 downto 1);
 
if ram_wrl = '1' then
ram_data(7 downto 0) <= cpu_data_out;
607,7 → 766,7
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
if dat_addr(5) = '1' then
if cpu_addr(0) = '1' then
ram_data_out <= ram_data(15 downto 8);
else
ram_data_out <= ram_data(7 downto 0);
617,7 → 776,7
--
-- Compact Flash Control
--
compact_flash: process( SysClk, Reset_n,
compact_flash: process( cpu_clk, Reset_n,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
cf_cs, cf_rd, cf_wr, cf_data_out )
begin
640,42 → 799,35
end process;
 
--
-- ROM Map switch
-- The Map switch output is initially set
-- On a Write to the Map Switch port, clear the Map Switch
-- and map the RAM in place of the boot ROM.
--
--map_proc : process( SysClk, Reset_n, map_cs, cpu_rw )
--begin
-- if SysClk'event and SysClk = '0' then
-- if Reset_n = '0' then
-- map_sw <= '1';
-- else
-- if (map_cs = '1') and (cpu_rw = '0') then
-- map_sw <= '0';
-- else
-- map_sw <= map_sw;
-- end if;
-- end if;
-- end if;
--end process;
 
--
-- Interrupts and other bus control signals
--
interrupts : process( Reset_n, uart_irq
-- ,timer_irq
interrupts : process( Reset_n, uart_irq,
trap_irq, timer_irq, keyboard_irq
)
begin
cpu_reset <= not Reset_n; -- CPU reset is active high
cpu_irq <= uart_irq;
-- cpu_nmi <= timer_irq;
cpu_nmi <= '0';
cpu_firq <= '0';
cpu_irq <= uart_irq or keyboard_irq;
cpu_nmi <= trap_irq;
cpu_firq <= timer_irq;
cpu_halt <= '0';
cpu_hold <= '0';
end process;
 
--
-- CPU bus signals
--
my_bus : process( cpu_clk, cpu_reset, cpu_rw, cpu_addr, cpu_data_out )
begin
bus_clk <= cpu_clk;
bus_reset <= cpu_reset;
bus_rw <= cpu_rw;
bus_addr <= cpu_addr;
if( cpu_rw = '1' ) then
bus_data <= "ZZZZZZZZ";
else
bus_data <= cpu_data_out;
end if;
end process;
 
--
-- flash led to indicate code is working
--
684,8 → 836,25
if(SysClk'event and SysClk = '0') then
countL <= countL + 1;
end if;
LED <= countL(21);
LED <= countL(23);
-- baudclk <= countL(5); -- 9.8MHz / 64 = 153,600 KHz = 9600Bd * 16
-- baudclk <= countL(4); -- 9.8MHz / 32 = 307,200 KHz = 19200Bd * 16
-- baudclk <= countL(3); -- 9.8MHz / 16 = 614,400 KHz = 38400Bd * 16
-- baudclk <= countL(2); -- 4.9MHz / 8 = 614,400 KHz = 38400Bd * 16
dcd_n <= '0';
end process;
 
my_clock: process( SysClk )
begin
if(SysClk'event and SysClk = '0') then
if( BaudCount = 26 ) then
BaudCount <= "00000";
else
BaudCount <= BaudCount + 1;
end if;
end if;
baudclk <= BaudCount(4); -- 25MHz / 27 = 926,000 KHz = 57,870Bd * 16
end process;
 
end my_computer; --===================== End of architecture =======================--
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.