- added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1418 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: cpu_embedded using cpu_core and rom
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
entity cpu_embedded is
|
||||
Port (
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
int_in : in STD_LOGIC;
|
||||
int_ack : out STD_LOGIC;
|
||||
xmem_we : out STD_LOGIC;
|
||||
xmem_re : out STD_LOGIC;
|
||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
|
||||
io_sel : out STD_LOGIC
|
||||
);
|
||||
end cpu_embedded;
|
||||
|
||||
architecture rtl of cpu_embedded is
|
||||
|
||||
signal irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||
signal irom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
|
||||
COMPONENT cpu
|
||||
Port (
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
int_in : in STD_LOGIC;
|
||||
int_ack : out STD_LOGIC;
|
||||
xmem_we : out STD_LOGIC;
|
||||
xmem_re : out STD_LOGIC;
|
||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||
instr_addr : out unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_addr : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
io_sel : out STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
|
||||
COMPONENT irom
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in inst_addr_t;
|
||||
dout : out inst_t
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
begin
|
||||
|
||||
inst_cpu: cpu
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
ce => ce,
|
||||
int_in => int_in,
|
||||
int_ack => int_ack,
|
||||
xmem_we => xmem_we,
|
||||
xmem_re => xmem_re,
|
||||
instr_din => irom_data,
|
||||
instr_addr => irom_addr,
|
||||
xmem_din => xmem_din,
|
||||
xmem_dout => xmem_dout,
|
||||
xmem_addr => xmem_addr,
|
||||
io_sel => io_sel
|
||||
);
|
||||
|
||||
inst_irom: irom
|
||||
PORT MAP(
|
||||
clk => clk,
|
||||
ce => ce,
|
||||
addr => irom_addr,
|
||||
dout => irom_data
|
||||
);
|
||||
|
||||
end rtl;
|
||||
@@ -0,0 +1,854 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: Types, constants and functions for JCPU
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
|
||||
package cpu_pkg is
|
||||
|
||||
-- Revision of the CPU
|
||||
constant REVISION : integer := 2;
|
||||
|
||||
-- Chipram depth (can be tweaked)
|
||||
constant CHIPRAM_SIZE_BITS : integer := 10;
|
||||
|
||||
-- Chipregister file depth
|
||||
constant CHIPREG_SIZE_BITS : integer := 8;
|
||||
|
||||
-- Number of registers (can be tweaked)
|
||||
constant REG_SIZE_BITS : integer := 4;
|
||||
|
||||
-- Instruction memory
|
||||
constant IMEM_ADDR_WIDTH : integer := 12;
|
||||
|
||||
-- Data memory
|
||||
constant DMEM_DATA_WIDTH : integer := 8;
|
||||
constant DMEM_ADDR_WIDTH : integer := 8;
|
||||
|
||||
-- Instruction format
|
||||
constant INST_OPCODE_WIDTH : integer := 6;
|
||||
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
||||
|
||||
-- Microcode ROM
|
||||
constant MUCODE_ADDR_WIDTH : integer := 9;
|
||||
|
||||
-- Stack depth
|
||||
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
||||
|
||||
--Types
|
||||
subtype iphase_t is integer range 0 to 1;
|
||||
type mem_access_t is (cmem_access, xmem_access, cio_access, xio_access);
|
||||
type reg_src_t is (alu_src, stk_src, cmem_src, xmem_src);
|
||||
type alu_src_t is (reg_a, reg_b, const);
|
||||
type ddata_src_t is (reg_a, reg_b, const);
|
||||
type daddr_src_t is (reg_a, reg_b, const);
|
||||
subtype instr_name_t is string(1 to 12);
|
||||
type instr_name_array_t is array (0 to 63) of instr_name_t;
|
||||
subtype opcode_t is unsigned (INST_OPCODE_WIDTH-1 downto 0);
|
||||
subtype inst_data_t is unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
subtype inst_addr_t is unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
subtype inst_t is unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||
subtype dmem_data_t is unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
subtype dmem_addr_t is unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
subtype reg_ptr_t is unsigned (3 downto 0);
|
||||
type dmem_array_t is array (natural range <>) of dmem_data_t;
|
||||
type instr_addr_array is array (integer range <>) of inst_addr_t;
|
||||
subtype page_sel_t is unsigned (CHIPRAM_SIZE_BITS-DMEM_DATA_WIDTH-2 downto 0);
|
||||
|
||||
type alu_op_t is
|
||||
(
|
||||
pass_op2,
|
||||
op1_add_op2,
|
||||
op1_sub_op2,
|
||||
op1_addc_op2,
|
||||
op1_subc_op2,
|
||||
op1_and_op2,
|
||||
op1_or_op2,
|
||||
op1_xor_op2,
|
||||
swap_op,
|
||||
shl_op,
|
||||
shr_op,
|
||||
rol_op,
|
||||
ror_op,
|
||||
rolc_op,
|
||||
rorc_op
|
||||
);
|
||||
|
||||
type alu_status_t is record
|
||||
zero : STD_LOGIC;
|
||||
carry : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type cpu_status_t is record
|
||||
alu : alu_status_t;
|
||||
end record;
|
||||
|
||||
type ctrl_lines_t is record
|
||||
reg_we : STD_LOGIC;
|
||||
reg_src_sel : reg_src_t;
|
||||
alu_op1_src_sel : alu_src_t;
|
||||
alu_op2_src_sel : alu_src_t;
|
||||
alu_opsel : alu_op_t;
|
||||
alu_load : STD_LOGIC;
|
||||
ddata_src_sel : ddata_src_t;
|
||||
daddr_src_sel : daddr_src_t;
|
||||
pc_load : STD_LOGIC;
|
||||
pc_inc : STD_LOGIC;
|
||||
stk_push : STD_LOGIC;
|
||||
stk_pop : STD_LOGIC;
|
||||
stk_pushd : STD_LOGIC;
|
||||
stk_popd : STD_LOGIC;
|
||||
mem_access : mem_access_t;
|
||||
mem_read : STD_LOGIC;
|
||||
mem_write : STD_LOGIC;
|
||||
int_exit : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type dpath_ctrl_out_t is record
|
||||
lines : ctrl_lines_t;
|
||||
reg_a_ptr : reg_ptr_t;
|
||||
reg_b_ptr : reg_ptr_t;
|
||||
end record;
|
||||
|
||||
type int_ctrl_in_t is record
|
||||
enable : std_logic;
|
||||
polarity : std_logic;
|
||||
edge_sens : std_logic;
|
||||
request : std_logic;
|
||||
end record;
|
||||
|
||||
type creg_ctrl_out_t is record
|
||||
page_sel : page_sel_t;
|
||||
int_ctrl : int_ctrl_in_t;
|
||||
stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||
cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||
end record;
|
||||
|
||||
type creg_ctrl_in_t is record
|
||||
alu : alu_status_t;
|
||||
end record;
|
||||
|
||||
|
||||
type murom_t is array (0 to integer(2**MUCODE_ADDR_WIDTH)-1) of ctrl_lines_t;
|
||||
|
||||
constant instr_name_array : instr_name_array_t :=
|
||||
(
|
||||
"NOP ", -- 00
|
||||
"HALT ", -- 01
|
||||
"MOV|R|R ", -- 02
|
||||
"MOV|R|K ", -- 03
|
||||
"MOVX|R|Ri ", -- 04
|
||||
"MOVX|R|Ki ", -- 05
|
||||
"MOVX|Ri|R ", -- 06
|
||||
"MOVX|Ri|K ", -- 07
|
||||
"MOVX|Ki|R ", -- 08
|
||||
"MOVC|R|Ri ", -- 09
|
||||
"MOVC|R|Ki ", -- 0A
|
||||
"MOVC|Ri|R ", -- 0B
|
||||
"MOVC|Ri|K ", -- 0C
|
||||
"MOVC|Ki|R ", -- 0D
|
||||
"CMP|R|R ", -- 0E
|
||||
"CMP|R|K ", -- 0F
|
||||
"ADD|R|R ", -- 10
|
||||
"ADD|R|K ", -- 11
|
||||
"ADDC|R|R ", -- 12
|
||||
"ADDC|R|K ", -- 13
|
||||
"SUB|R|R ", -- 14
|
||||
"SUB|R|K ", -- 15
|
||||
"SUBC|R|R ", -- 16
|
||||
"SUBC|R|K ", -- 17
|
||||
"AND|R|R ", -- 18
|
||||
"AND|R|K ", -- 19
|
||||
"OR|R|R ", -- 1A
|
||||
"OR|R|K ", -- 1B
|
||||
"XOR|R|R ", -- 1C
|
||||
"XOR|R|K ", -- 1D
|
||||
"SHL|R ", -- 1E
|
||||
"SHR|R ", -- 1F
|
||||
"ROL|R ", -- 20
|
||||
"ROR|R ", -- 21
|
||||
"ROLC|R ", -- 22
|
||||
"RORC|R ", -- 23
|
||||
"XOUT|Ki|R ", -- 24
|
||||
"XOUT|Ri|K ", -- 25
|
||||
"COUT|Ki|R ", -- 26
|
||||
"COUT|Ri|K ", -- 27
|
||||
"XIN|R|Ki ", -- 28
|
||||
"CIN|R|Ki ", -- 29
|
||||
"SWAP|R ", -- 2A
|
||||
"UNDEF ", -- 2B
|
||||
"UNDEF ", -- 2C
|
||||
"UNDEF ", -- 2D
|
||||
"SUB|K|R ", -- 2E
|
||||
"SUBC|K|R ", -- 2F
|
||||
"JMP|K ", -- 30
|
||||
"JZ|K ", -- 31
|
||||
"JNZ|K ", -- 32
|
||||
"JC|K ", -- 33
|
||||
"JNC|K ", -- 34
|
||||
"JLT|K ", -- 35
|
||||
"JGT|K ", -- 36
|
||||
"JLE|K ", -- 37
|
||||
"JGE|K ", -- 38
|
||||
"JEQ|K ", -- 39
|
||||
"JNE|K ", -- 3A
|
||||
"CALL|K ", -- 3B
|
||||
"PUSH|R ", -- 3C
|
||||
"POP|R ", -- 3D
|
||||
"RET ", -- 3E
|
||||
"RETI " -- 3F
|
||||
);
|
||||
-- Functions
|
||||
function Instr(opcode : opcode_t) return inst_t;
|
||||
function Instr(opcode : opcode_t; data : inst_data_t) return inst_t;
|
||||
function Instr(opcode : opcode_t; data : inst_data_t; reg : integer) return inst_t;
|
||||
function Instr(opcode : opcode_t; reg_a : integer) return inst_t;
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b : integer) return inst_t;
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b, reg_c : integer) return inst_t;
|
||||
function ctrl_lines_default return ctrl_lines_t;
|
||||
function idecoder(instr_name : instr_name_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t;
|
||||
function idecoder(opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t;
|
||||
function gen_murom return murom_t;
|
||||
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return unsigned;
|
||||
function MIN (X, Y: INTEGER) return INTEGER;
|
||||
function MAX (X, Y: INTEGER) return INTEGER;
|
||||
|
||||
end cpu_pkg;
|
||||
|
||||
package body cpu_pkg is
|
||||
|
||||
function Instr(opcode : opcode_t) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; data : inst_data_t) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(inst_t'length-opcode_t'length-1 downto inst_t'length-opcode_t'length-inst_addr_t'length) := data;
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; data : inst_data_t; reg : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(inst_t'length-opcode_t'length-1 downto inst_t'length-opcode_t'length-inst_data_t'length) := data;
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; reg_a : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_b, reg_ptr_t'length));
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b, reg_c : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(3*(reg_ptr_t'length)-1 downto 2*reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_c, reg_ptr_t'length));
|
||||
inst(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_b, reg_ptr_t'length));
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function ctrl_lines_default return ctrl_lines_t is
|
||||
variable result : ctrl_lines_t;
|
||||
begin
|
||||
result.pc_load := '0';
|
||||
result.pc_inc := '0';
|
||||
result.stk_push := '0';
|
||||
result.stk_pop := '0';
|
||||
result.stk_pushd := '0';
|
||||
result.stk_popd := '0';
|
||||
result.reg_we := '0';
|
||||
result.reg_src_sel := alu_src;
|
||||
result.ddata_src_sel := reg_a;
|
||||
result.daddr_src_sel := reg_b;
|
||||
result.alu_opsel := pass_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.alu_load := '0';
|
||||
result.mem_access := cmem_access;
|
||||
result.mem_read := '0';
|
||||
result.mem_write := '0';
|
||||
result.int_exit := '0';
|
||||
return result;
|
||||
|
||||
end ctrl_lines_default;
|
||||
|
||||
function idecoder(opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t is
|
||||
variable instr_name : instr_name_t;
|
||||
begin
|
||||
instr_name := instr_name_array(to_integer(opcode));
|
||||
return idecoder(instr_name, iphase, alu_status);
|
||||
end idecoder;
|
||||
|
||||
function idecoder(instr_name : instr_name_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t is
|
||||
variable result : ctrl_lines_t;
|
||||
variable ze, cy : STD_LOGIC;
|
||||
|
||||
begin
|
||||
ze := alu_status.zero;
|
||||
cy := alu_status.carry;
|
||||
|
||||
result := ctrl_lines_default;
|
||||
if iphase = 0 then
|
||||
result.pc_inc := '1';
|
||||
end if;
|
||||
|
||||
case instr_name is
|
||||
|
||||
when "HALT " =>
|
||||
result.pc_inc := '0';
|
||||
when "MOV|R|R " => -- R(a) <= R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := pass_op2;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOV|R|K " => -- R(a) <= #kk
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := pass_op2;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVC|Ri|R " => -- [R(b)] <= R(a)
|
||||
result.mem_access := cmem_access;
|
||||
result.daddr_src_sel := reg_b;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVC|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := cmem_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "COUT|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := cio_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVC|R|Ri " => -- R(a) <= [R(b)]
|
||||
result.mem_access := cmem_access;
|
||||
result.reg_src_sel := cmem_src;
|
||||
result.daddr_src_sel := reg_b;
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVC|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := cmem_access;
|
||||
result.reg_src_sel := cmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "CIN|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := cio_access;
|
||||
result.reg_src_sel := cmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVC|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := cmem_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "COUT|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := cio_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVX|Ri|R " => -- [R(b)] <= R(a)
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := reg_b;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := xio_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
||||
result.mem_access := xmem_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := reg_b;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := xmem_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := xio_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := xio_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_add_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ADD|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_add_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ADDC|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_addc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ADDC|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_addc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUB|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUB|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUB|K|R " => -- R(a) <= k - R(a)
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := const;
|
||||
result.alu_op2_src_sel := reg_a;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUBC|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_subc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUBC|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_subc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUBC|K|R " => -- R(a) <= K - R(a)
|
||||
result.alu_opsel := op1_subc_op2;
|
||||
result.alu_op1_src_sel := const;
|
||||
result.alu_op2_src_sel := reg_a;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "AND|R|R " => -- R(a) <= R(a) and R(b)
|
||||
result.alu_opsel := op1_and_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "AND|R|K " => -- R(a) <= R(a) and k
|
||||
result.alu_opsel := op1_and_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "OR|R|R " => -- R(a) <= R(a) or R(b)
|
||||
result.alu_opsel := op1_or_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "OR|R|K " => -- R(a) <= R(a) or R(b)
|
||||
result.alu_opsel := op1_or_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "XOR|R|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.alu_opsel := op1_xor_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "XOR|R|K " => -- R(a) <= R(a) xor R(b)
|
||||
result.alu_opsel := op1_xor_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SWAP|R " => -- R(a) <= R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := swap_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SHL|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := shl_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SHR|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := shr_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ROL|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := rol_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ROR|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := ror_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ROLC|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := rolc_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "RORC|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := rorc_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "CMP|R|R " => --
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.alu_load := '1';
|
||||
when "CMP|R|K " => --
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.alu_load := '1';
|
||||
when "JMP|K " => -- PC <= #addr
|
||||
if iphase = 0 then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
when "JZ|K " => -- PC <= #addr, zero
|
||||
if iphase = 0 then
|
||||
if ze = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JNZ|K " => -- PC <= #addr, !zero
|
||||
if iphase = 0 then
|
||||
if ze = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JC|K " => -- PC <= #addr, carry
|
||||
if iphase = 0 then
|
||||
if cy = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JNC|K " => -- PC <= #addr, !carry
|
||||
if iphase = 0 then
|
||||
if cy = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JLT|K " => -- PC <= #addr, !carry
|
||||
if iphase = 0 then
|
||||
if cy = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JGT|K " => --
|
||||
if iphase = 0 then
|
||||
if (cy or ze) = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JLE|K " => --
|
||||
if iphase = 0 then
|
||||
if (cy xor ze) = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JGE|K " => --
|
||||
if iphase = 0 then
|
||||
if (not cy or ze) = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JEQ|K " => --
|
||||
if iphase = 0 then
|
||||
if ze = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JNE|K " => --
|
||||
if iphase = 0 then
|
||||
if ze = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "PUSH|R " => -- push
|
||||
if iphase = 0 then
|
||||
result.stk_pushd := '1';
|
||||
end if;
|
||||
when "POP|R " => -- pop
|
||||
result.reg_src_sel := stk_src;
|
||||
if iphase = 0 then
|
||||
result.stk_popd := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "CALL|K " => -- call
|
||||
if iphase = 0 then
|
||||
result.pc_load := '1';
|
||||
result.stk_push := '1';
|
||||
end if;
|
||||
when "RET " => -- return
|
||||
if iphase = 0 then
|
||||
result.pc_load := '1';
|
||||
result.stk_pop := '1';
|
||||
end if;
|
||||
when "RETI " => -- return
|
||||
result.pc_inc := '0';
|
||||
result.int_exit := '1';
|
||||
|
||||
when others => null; -- nop
|
||||
end case;
|
||||
|
||||
return result;
|
||||
|
||||
end idecoder;
|
||||
|
||||
function gen_murom return murom_t is
|
||||
variable result : murom_t;
|
||||
variable opcode : opcode_t;
|
||||
variable iphase : iphase_t;
|
||||
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||
variable alu_status : alu_status_t;
|
||||
variable pos : integer := 0;
|
||||
|
||||
begin
|
||||
for i in 0 to 2**addr'length-1 loop
|
||||
addr := to_unsigned(i, addr'length);
|
||||
opcode := addr(opcode'length-1 downto 0);
|
||||
pos := opcode'length;
|
||||
iphase := 0;
|
||||
if addr(pos) = '1' then
|
||||
iphase := 1;
|
||||
end if;
|
||||
pos := pos + 1;
|
||||
alu_status.zero := addr(pos);
|
||||
pos := pos + 1;
|
||||
alu_status.carry := addr(pos);
|
||||
|
||||
result(i) := idecoder(opcode, iphase, alu_status);
|
||||
end loop;
|
||||
|
||||
return result;
|
||||
end gen_murom;
|
||||
|
||||
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return unsigned is
|
||||
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||
begin
|
||||
addr := alu_status.carry & alu_status.zero & to_unsigned(iphase, 1) & opcode;
|
||||
return addr;
|
||||
|
||||
end get_muromaddr;
|
||||
|
||||
-------------------------------------------------------------
|
||||
function MIN (X, Y: INTEGER) return INTEGER is
|
||||
variable res : integer := X;
|
||||
begin
|
||||
if Y < X then
|
||||
res := Y;
|
||||
end if;
|
||||
|
||||
return res;
|
||||
|
||||
end MIN;
|
||||
|
||||
-------------------------------------------------------------
|
||||
function MAX (X, Y: INTEGER) return INTEGER is
|
||||
variable res : integer := X;
|
||||
begin
|
||||
if Y > X then
|
||||
res := Y;
|
||||
end if;
|
||||
|
||||
return res;
|
||||
|
||||
end MAX;
|
||||
|
||||
|
||||
end cpu_pkg;
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: The ROM file for use in your VHDL design
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
-- JASM_ROM_INSERT_HERE
|
||||
ENTITY irom IS
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in inst_addr_t;
|
||||
dout : out inst_t
|
||||
);
|
||||
END irom;
|
||||
|
||||
ARCHITECTURE main OF irom IS
|
||||
|
||||
type imem_rom_t is array (0 to 168) of inst_t;
|
||||
|
||||
-- Assembled from main.jsm
|
||||
constant imem_rom : imem_rom_t :=
|
||||
(
|
||||
"110000" & X"002", -- 0x000: JMP 0x002
|
||||
"111111" & X"000", -- 0x001: RETI
|
||||
"101000" & X"0B0", -- 0x002: XIN R00, (0x0B)
|
||||
"100100" & X"010", -- 0x003: XOUT (0x01), R00
|
||||
"011001" & X"010", -- 0x004: AND R00, 0x01
|
||||
"110001" & X"002", -- 0x005: JZ 0x002
|
||||
"101000" & X"0B0", -- 0x006: XIN R00, (0x0B)
|
||||
"100100" & X"010", -- 0x007: XOUT (0x01), R00
|
||||
"111011" & X"06E", -- 0x008: CALL 0x06E
|
||||
"111011" & X"055", -- 0x009: CALL 0x055
|
||||
"000011" & X"000", -- 0x00A: MOV R00, 0x00
|
||||
"000011" & X"001", -- 0x00B: MOV R01, 0x00
|
||||
"111011" & X"05A", -- 0x00C: CALL 0x05A
|
||||
"111011" & X"074", -- 0x00D: CALL 0x074
|
||||
"000011" & X"030", -- 0x00E: MOV R00, 0x03
|
||||
"111011" & X"06B", -- 0x00F: CALL 0x06B
|
||||
"101001" & X"000", -- 0x010: CIN R00, (0x00)
|
||||
"010001" & X"300", -- 0x011: ADD R00, 0x30
|
||||
"111011" & X"05E", -- 0x012: CALL 0x05E
|
||||
"000011" & X"000", -- 0x013: MOV R00, 0x00
|
||||
"111011" & X"061", -- 0x014: CALL 0x061
|
||||
"111011" & X"074", -- 0x015: CALL 0x074
|
||||
"111011" & X"074", -- 0x016: CALL 0x074
|
||||
"000011" & X"0D0", -- 0x017: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x018: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x019: CALL 0x07B
|
||||
"000011" & X"000", -- 0x01A: MOV R00, 0x00
|
||||
"000011" & X"031", -- 0x01B: MOV R01, 0x03
|
||||
"111011" & X"05A", -- 0x01C: CALL 0x05A
|
||||
"000011" & X"160", -- 0x01D: MOV R00, 0x16
|
||||
"111011" & X"06B", -- 0x01E: CALL 0x06B
|
||||
"111011" & X"074", -- 0x01F: CALL 0x074
|
||||
"000011" & X"000", -- 0x020: MOV R00, 0x00
|
||||
"000011" & X"0A1", -- 0x021: MOV R01, 0x0A
|
||||
"111011" & X"05A", -- 0x022: CALL 0x05A
|
||||
"000011" & X"A0F", -- 0x023: MOV R15, 0xA0
|
||||
"001111" & X"00F", -- 0x024: TST R15
|
||||
"110001" & X"02F", -- 0x025: JZ 0x02F
|
||||
"010101" & X"01F", -- 0x026: DEC R15
|
||||
"000011" & X"301", -- 0x027: MOV R01, 0x30
|
||||
"001111" & X"3A1", -- 0x028: CMP R01, 0x3A
|
||||
"111001" & X"02E", -- 0x029: JEQ 0x02E
|
||||
"000010" & X"010", -- 0x02A: MOV R00, R01
|
||||
"010001" & X"011", -- 0x02B: INC R01
|
||||
"111011" & X"05E", -- 0x02C: CALL 0x05E
|
||||
"110000" & X"028", -- 0x02D: JMP 0x028
|
||||
"110000" & X"024", -- 0x02E: JMP 0x024
|
||||
"111011" & X"074", -- 0x02F: CALL 0x074
|
||||
"000011" & X"000", -- 0x030: MOV R00, 0x00
|
||||
"000011" & X"0C1", -- 0x031: MOV R01, 0x0C
|
||||
"111011" & X"05A", -- 0x032: CALL 0x05A
|
||||
"111011" & X"050", -- 0x033: CALL 0x050
|
||||
"000011" & X"000", -- 0x034: MOV R00, 0x00
|
||||
"000011" & X"1E1", -- 0x035: MOV R01, 0x1E
|
||||
"111011" & X"05A", -- 0x036: CALL 0x05A
|
||||
"000011" & X"0D0", -- 0x037: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x038: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x039: CALL 0x07B
|
||||
"000011" & X"0D0", -- 0x03A: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x03B: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x03C: CALL 0x07B
|
||||
"000011" & X"0D0", -- 0x03D: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x03E: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x03F: CALL 0x07B
|
||||
"000011" & X"0D0", -- 0x040: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x041: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x042: CALL 0x07B
|
||||
"000011" & X"0D0", -- 0x043: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x044: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x045: CALL 0x07B
|
||||
"000011" & X"0D0", -- 0x046: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x047: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x048: CALL 0x07B
|
||||
"000011" & X"0D0", -- 0x049: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x04A: CALL 0x06B
|
||||
"111011" & X"07B", -- 0x04B: CALL 0x07B
|
||||
"000011" & X"0D0", -- 0x04C: MOV R00, 0x0D
|
||||
"111011" & X"06B", -- 0x04D: CALL 0x06B
|
||||
"111011" & X"074", -- 0x04E: CALL 0x074
|
||||
"110000" & X"008", -- 0x04F: JMP 0x008
|
||||
"111100" & X"000", -- 0x050: PUSH R00
|
||||
"000011" & X"020", -- 0x051: MOV R00, 0x02
|
||||
"100100" & X"0B0", -- 0x052: XOUT (0x0B), R00
|
||||
"111101" & X"000", -- 0x053: POP R00
|
||||
"111110" & X"000", -- 0x054: RET
|
||||
"111100" & X"000", -- 0x055: PUSH R00
|
||||
"000011" & X"010", -- 0x056: MOV R00, 0x01
|
||||
"100100" & X"0B0", -- 0x057: XOUT (0x0B), R00
|
||||
"111101" & X"000", -- 0x058: POP R00
|
||||
"111110" & X"000", -- 0x059: RET
|
||||
"111011" & X"06E", -- 0x05A: CALL 0x06E
|
||||
"100100" & X"091", -- 0x05B: XOUT (0x09), R01
|
||||
"100100" & X"080", -- 0x05C: XOUT (0x08), R00
|
||||
"111110" & X"000", -- 0x05D: RET
|
||||
"111011" & X"06E", -- 0x05E: CALL 0x06E
|
||||
"100100" & X"0A0", -- 0x05F: XOUT (0x0A), R00
|
||||
"111110" & X"000", -- 0x060: RET
|
||||
"111100" & X"001", -- 0x061: PUSH R01
|
||||
"000010" & X"001", -- 0x062: MOV R01, R00
|
||||
"000100" & X"010", -- 0x063: MOVX R00, (R01)
|
||||
"010001" & X"011", -- 0x064: INC R01
|
||||
"001111" & X"000", -- 0x065: TST R00
|
||||
"110001" & X"069", -- 0x066: JZ 0x069
|
||||
"111011" & X"05E", -- 0x067: CALL 0x05E
|
||||
"110000" & X"063", -- 0x068: JMP 0x063
|
||||
"111101" & X"001", -- 0x069: POP R01
|
||||
"111110" & X"000", -- 0x06A: RET
|
||||
"111011" & X"050", -- 0x06B: CALL 0x050
|
||||
"111011" & X"061", -- 0x06C: CALL 0x061
|
||||
"111110" & X"000", -- 0x06D: RET
|
||||
"111100" & X"000", -- 0x06E: PUSH R00
|
||||
"101000" & X"0B0", -- 0x06F: XIN R00, (0x0B)
|
||||
"011001" & X"020", -- 0x070: AND R00, 0x02
|
||||
"110001" & X"06F", -- 0x071: JZ 0x06F
|
||||
"111101" & X"000", -- 0x072: POP R00
|
||||
"111110" & X"000", -- 0x073: RET
|
||||
"111100" & X"00F", -- 0x074: PUSH R15
|
||||
"000011" & X"0AF", -- 0x075: MOV R15, 0x0A
|
||||
"111011" & X"07B", -- 0x076: CALL 0x07B
|
||||
"010101" & X"01F", -- 0x077: DEC R15
|
||||
"110010" & X"076", -- 0x078: JNZ 0x076
|
||||
"111101" & X"00F", -- 0x079: POP R15
|
||||
"111110" & X"000", -- 0x07A: RET
|
||||
"111100" & X"00F", -- 0x07B: PUSH R15
|
||||
"000011" & X"0AF", -- 0x07C: MOV R15, 0x0A
|
||||
"111011" & X"082", -- 0x07D: CALL 0x082
|
||||
"010101" & X"01F", -- 0x07E: DEC R15
|
||||
"110010" & X"07D", -- 0x07F: JNZ 0x07D
|
||||
"111101" & X"00F", -- 0x080: POP R15
|
||||
"111110" & X"000", -- 0x081: RET
|
||||
"111100" & X"00F", -- 0x082: PUSH R15
|
||||
"000011" & X"0AF", -- 0x083: MOV R15, 0x0A
|
||||
"111011" & X"089", -- 0x084: CALL 0x089
|
||||
"010101" & X"01F", -- 0x085: DEC R15
|
||||
"110010" & X"084", -- 0x086: JNZ 0x084
|
||||
"111101" & X"00F", -- 0x087: POP R15
|
||||
"111110" & X"000", -- 0x088: RET
|
||||
"111100" & X"00F", -- 0x089: PUSH R15
|
||||
"000011" & X"0AF", -- 0x08A: MOV R15, 0x0A
|
||||
"111011" & X"090", -- 0x08B: CALL 0x090
|
||||
"010101" & X"01F", -- 0x08C: DEC R15
|
||||
"110010" & X"08B", -- 0x08D: JNZ 0x08B
|
||||
"111101" & X"00F", -- 0x08E: POP R15
|
||||
"111110" & X"000", -- 0x08F: RET
|
||||
"111100" & X"00F", -- 0x090: PUSH R15
|
||||
"000011" & X"0AF", -- 0x091: MOV R15, 0x0A
|
||||
"111011" & X"097", -- 0x092: CALL 0x097
|
||||
"010101" & X"01F", -- 0x093: DEC R15
|
||||
"110010" & X"092", -- 0x094: JNZ 0x092
|
||||
"111101" & X"00F", -- 0x095: POP R15
|
||||
"111110" & X"000", -- 0x096: RET
|
||||
"111100" & X"00F", -- 0x097: PUSH R15
|
||||
"000011" & X"63F", -- 0x098: MOV R15, 0x63
|
||||
"000000" & X"000", -- 0x099: NOP
|
||||
"000000" & X"000", -- 0x09A: NOP
|
||||
"000000" & X"000", -- 0x09B: NOP
|
||||
"010101" & X"01F", -- 0x09C: DEC R15
|
||||
"110010" & X"099", -- 0x09D: JNZ 0x099
|
||||
"111101" & X"00F", -- 0x09E: POP R15
|
||||
"111110" & X"000", -- 0x09F: RET
|
||||
"111100" & X"00F", -- 0x0A0: PUSH R15
|
||||
"000011" & X"09F", -- 0x0A1: MOV R15, 0x09
|
||||
"000000" & X"000", -- 0x0A2: NOP
|
||||
"000000" & X"000", -- 0x0A3: NOP
|
||||
"000000" & X"000", -- 0x0A4: NOP
|
||||
"010101" & X"01F", -- 0x0A5: DEC R15
|
||||
"110010" & X"0A2", -- 0x0A6: JNZ 0x0A2
|
||||
"111101" & X"00F", -- 0x0A7: POP R15
|
||||
"111110" & X"000" -- 0x0A8: RET
|
||||
);
|
||||
|
||||
begin
|
||||
|
||||
PROM_READ:
|
||||
process(clk, ce)
|
||||
begin
|
||||
if rising_edge(clk) and ce = '1' then
|
||||
dout <= imem_rom(to_integer(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end main;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,317 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: The ROM file for use in your VHDL design
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
-- JASM_ROM_INSERT_HERE
|
||||
ENTITY xrom IS
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in dmem_addr_t;
|
||||
dout : out dmem_data_t
|
||||
);
|
||||
END xrom;
|
||||
|
||||
ARCHITECTURE main OF xrom IS
|
||||
|
||||
type xmem_rom_t is array (0 to 255) of dmem_data_t;
|
||||
|
||||
-- Assembled from main.jsm
|
||||
constant xmem_rom : xmem_rom_t :=
|
||||
(
|
||||
X"0D", -- 0x00
|
||||
X"0A", -- 0x01
|
||||
X"00", -- 0x02
|
||||
X"4A", -- 0x03
|
||||
X"2D", -- 0x04
|
||||
X"43", -- 0x05
|
||||
X"50", -- 0x06
|
||||
X"55", -- 0x07
|
||||
X"20", -- 0x08
|
||||
X"56", -- 0x09
|
||||
X"31", -- 0x0A
|
||||
X"2E", -- 0x0B
|
||||
X"00", -- 0x0C
|
||||
X"52", -- 0x0D
|
||||
X"65", -- 0x0E
|
||||
X"61", -- 0x0F
|
||||
X"64", -- 0x10
|
||||
X"79", -- 0x11
|
||||
X"2E", -- 0x12
|
||||
X"0D", -- 0x13
|
||||
X"0A", -- 0x14
|
||||
X"00", -- 0x15
|
||||
X"4D", -- 0x16
|
||||
X"69", -- 0x17
|
||||
X"6D", -- 0x18
|
||||
X"69", -- 0x19
|
||||
X"20", -- 0x1A
|
||||
X"69", -- 0x1B
|
||||
X"73", -- 0x1C
|
||||
X"74", -- 0x1D
|
||||
X"20", -- 0x1E
|
||||
X"65", -- 0x1F
|
||||
X"69", -- 0x20
|
||||
X"6E", -- 0x21
|
||||
X"65", -- 0x22
|
||||
X"20", -- 0x23
|
||||
X"6C", -- 0x24
|
||||
X"69", -- 0x25
|
||||
X"65", -- 0x26
|
||||
X"62", -- 0x27
|
||||
X"65", -- 0x28
|
||||
X"20", -- 0x29
|
||||
X"4B", -- 0x2A
|
||||
X"61", -- 0x2B
|
||||
X"74", -- 0x2C
|
||||
X"7A", -- 0x2D
|
||||
X"65", -- 0x2E
|
||||
X"20", -- 0x2F
|
||||
X"21", -- 0x30
|
||||
X"21", -- 0x31
|
||||
X"21", -- 0x32
|
||||
X"0D", -- 0x33
|
||||
X"0A", -- 0x34
|
||||
X"00", -- 0x35
|
||||
X"00", -- 0x36
|
||||
X"00", -- 0x37
|
||||
X"00", -- 0x38
|
||||
X"00", -- 0x39
|
||||
X"00", -- 0x3A
|
||||
X"00", -- 0x3B
|
||||
X"00", -- 0x3C
|
||||
X"00", -- 0x3D
|
||||
X"00", -- 0x3E
|
||||
X"00", -- 0x3F
|
||||
X"00", -- 0x40
|
||||
X"00", -- 0x41
|
||||
X"00", -- 0x42
|
||||
X"00", -- 0x43
|
||||
X"00", -- 0x44
|
||||
X"00", -- 0x45
|
||||
X"00", -- 0x46
|
||||
X"00", -- 0x47
|
||||
X"00", -- 0x48
|
||||
X"00", -- 0x49
|
||||
X"00", -- 0x4A
|
||||
X"00", -- 0x4B
|
||||
X"00", -- 0x4C
|
||||
X"00", -- 0x4D
|
||||
X"00", -- 0x4E
|
||||
X"00", -- 0x4F
|
||||
X"00", -- 0x50
|
||||
X"00", -- 0x51
|
||||
X"00", -- 0x52
|
||||
X"00", -- 0x53
|
||||
X"00", -- 0x54
|
||||
X"00", -- 0x55
|
||||
X"00", -- 0x56
|
||||
X"00", -- 0x57
|
||||
X"00", -- 0x58
|
||||
X"00", -- 0x59
|
||||
X"00", -- 0x5A
|
||||
X"00", -- 0x5B
|
||||
X"00", -- 0x5C
|
||||
X"00", -- 0x5D
|
||||
X"00", -- 0x5E
|
||||
X"00", -- 0x5F
|
||||
X"00", -- 0x60
|
||||
X"00", -- 0x61
|
||||
X"00", -- 0x62
|
||||
X"00", -- 0x63
|
||||
X"00", -- 0x64
|
||||
X"00", -- 0x65
|
||||
X"00", -- 0x66
|
||||
X"00", -- 0x67
|
||||
X"00", -- 0x68
|
||||
X"00", -- 0x69
|
||||
X"00", -- 0x6A
|
||||
X"00", -- 0x6B
|
||||
X"00", -- 0x6C
|
||||
X"00", -- 0x6D
|
||||
X"00", -- 0x6E
|
||||
X"00", -- 0x6F
|
||||
X"00", -- 0x70
|
||||
X"00", -- 0x71
|
||||
X"00", -- 0x72
|
||||
X"00", -- 0x73
|
||||
X"00", -- 0x74
|
||||
X"00", -- 0x75
|
||||
X"00", -- 0x76
|
||||
X"00", -- 0x77
|
||||
X"00", -- 0x78
|
||||
X"00", -- 0x79
|
||||
X"00", -- 0x7A
|
||||
X"00", -- 0x7B
|
||||
X"00", -- 0x7C
|
||||
X"00", -- 0x7D
|
||||
X"00", -- 0x7E
|
||||
X"00", -- 0x7F
|
||||
X"00", -- 0x80
|
||||
X"00", -- 0x81
|
||||
X"00", -- 0x82
|
||||
X"00", -- 0x83
|
||||
X"00", -- 0x84
|
||||
X"00", -- 0x85
|
||||
X"00", -- 0x86
|
||||
X"00", -- 0x87
|
||||
X"00", -- 0x88
|
||||
X"00", -- 0x89
|
||||
X"00", -- 0x8A
|
||||
X"00", -- 0x8B
|
||||
X"00", -- 0x8C
|
||||
X"00", -- 0x8D
|
||||
X"00", -- 0x8E
|
||||
X"00", -- 0x8F
|
||||
X"00", -- 0x90
|
||||
X"00", -- 0x91
|
||||
X"00", -- 0x92
|
||||
X"00", -- 0x93
|
||||
X"00", -- 0x94
|
||||
X"00", -- 0x95
|
||||
X"00", -- 0x96
|
||||
X"00", -- 0x97
|
||||
X"00", -- 0x98
|
||||
X"00", -- 0x99
|
||||
X"00", -- 0x9A
|
||||
X"00", -- 0x9B
|
||||
X"00", -- 0x9C
|
||||
X"00", -- 0x9D
|
||||
X"00", -- 0x9E
|
||||
X"00", -- 0x9F
|
||||
X"00", -- 0xA0
|
||||
X"00", -- 0xA1
|
||||
X"00", -- 0xA2
|
||||
X"00", -- 0xA3
|
||||
X"00", -- 0xA4
|
||||
X"00", -- 0xA5
|
||||
X"00", -- 0xA6
|
||||
X"00", -- 0xA7
|
||||
X"00", -- 0xA8
|
||||
X"00", -- 0xA9
|
||||
X"00", -- 0xAA
|
||||
X"00", -- 0xAB
|
||||
X"00", -- 0xAC
|
||||
X"00", -- 0xAD
|
||||
X"00", -- 0xAE
|
||||
X"00", -- 0xAF
|
||||
X"00", -- 0xB0
|
||||
X"00", -- 0xB1
|
||||
X"00", -- 0xB2
|
||||
X"00", -- 0xB3
|
||||
X"00", -- 0xB4
|
||||
X"00", -- 0xB5
|
||||
X"00", -- 0xB6
|
||||
X"00", -- 0xB7
|
||||
X"00", -- 0xB8
|
||||
X"00", -- 0xB9
|
||||
X"00", -- 0xBA
|
||||
X"00", -- 0xBB
|
||||
X"00", -- 0xBC
|
||||
X"00", -- 0xBD
|
||||
X"00", -- 0xBE
|
||||
X"00", -- 0xBF
|
||||
X"00", -- 0xC0
|
||||
X"00", -- 0xC1
|
||||
X"00", -- 0xC2
|
||||
X"00", -- 0xC3
|
||||
X"00", -- 0xC4
|
||||
X"00", -- 0xC5
|
||||
X"00", -- 0xC6
|
||||
X"00", -- 0xC7
|
||||
X"00", -- 0xC8
|
||||
X"00", -- 0xC9
|
||||
X"00", -- 0xCA
|
||||
X"00", -- 0xCB
|
||||
X"00", -- 0xCC
|
||||
X"00", -- 0xCD
|
||||
X"00", -- 0xCE
|
||||
X"00", -- 0xCF
|
||||
X"00", -- 0xD0
|
||||
X"00", -- 0xD1
|
||||
X"00", -- 0xD2
|
||||
X"00", -- 0xD3
|
||||
X"00", -- 0xD4
|
||||
X"00", -- 0xD5
|
||||
X"00", -- 0xD6
|
||||
X"00", -- 0xD7
|
||||
X"00", -- 0xD8
|
||||
X"00", -- 0xD9
|
||||
X"00", -- 0xDA
|
||||
X"00", -- 0xDB
|
||||
X"00", -- 0xDC
|
||||
X"00", -- 0xDD
|
||||
X"00", -- 0xDE
|
||||
X"00", -- 0xDF
|
||||
X"00", -- 0xE0
|
||||
X"00", -- 0xE1
|
||||
X"00", -- 0xE2
|
||||
X"00", -- 0xE3
|
||||
X"00", -- 0xE4
|
||||
X"00", -- 0xE5
|
||||
X"00", -- 0xE6
|
||||
X"00", -- 0xE7
|
||||
X"00", -- 0xE8
|
||||
X"00", -- 0xE9
|
||||
X"00", -- 0xEA
|
||||
X"00", -- 0xEB
|
||||
X"00", -- 0xEC
|
||||
X"00", -- 0xED
|
||||
X"00", -- 0xEE
|
||||
X"00", -- 0xEF
|
||||
X"00", -- 0xF0
|
||||
X"00", -- 0xF1
|
||||
X"00", -- 0xF2
|
||||
X"00", -- 0xF3
|
||||
X"00", -- 0xF4
|
||||
X"00", -- 0xF5
|
||||
X"00", -- 0xF6
|
||||
X"00", -- 0xF7
|
||||
X"00", -- 0xF8
|
||||
X"00", -- 0xF9
|
||||
X"00", -- 0xFA
|
||||
X"00", -- 0xFB
|
||||
X"00", -- 0xFC
|
||||
X"00", -- 0xFD
|
||||
X"00", -- 0xFE
|
||||
X"00" -- 0xFF
|
||||
);
|
||||
|
||||
begin
|
||||
|
||||
PROM_READ:
|
||||
process(clk, ce)
|
||||
begin
|
||||
if rising_edge(clk) and ce = '1' then
|
||||
dout <= xmem_rom(to_integer(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end main;
|
||||
|
||||
@@ -0,0 +1,413 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: loadable ROM
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
library work;
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
ENTITY xrom IS
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in dmem_addr_t;
|
||||
dout : out dmem_data_t
|
||||
);
|
||||
|
||||
END xrom;
|
||||
|
||||
ARCHITECTURE loadable OF xrom IS
|
||||
|
||||
-- JASM_ROM_INSERT_HERE
|
||||
|
||||
-- Assembled from main.jsm
|
||||
type xmem_rom_t is array (0 to 255) of dmem_data_t;
|
||||
signal xmem_rom : xmem_rom_t :=
|
||||
(
|
||||
X"0D", -- 0x00
|
||||
X"0A", -- 0x01
|
||||
X"00", -- 0x02
|
||||
X"4A", -- 0x03
|
||||
X"2D", -- 0x04
|
||||
X"43", -- 0x05
|
||||
X"50", -- 0x06
|
||||
X"55", -- 0x07
|
||||
X"20", -- 0x08
|
||||
X"56", -- 0x09
|
||||
X"31", -- 0x0A
|
||||
X"2E", -- 0x0B
|
||||
X"00", -- 0x0C
|
||||
X"52", -- 0x0D
|
||||
X"65", -- 0x0E
|
||||
X"61", -- 0x0F
|
||||
X"64", -- 0x10
|
||||
X"79", -- 0x11
|
||||
X"2E", -- 0x12
|
||||
X"0D", -- 0x13
|
||||
X"0A", -- 0x14
|
||||
X"00", -- 0x15
|
||||
X"4D", -- 0x16
|
||||
X"69", -- 0x17
|
||||
X"6D", -- 0x18
|
||||
X"69", -- 0x19
|
||||
X"20", -- 0x1A
|
||||
X"69", -- 0x1B
|
||||
X"73", -- 0x1C
|
||||
X"74", -- 0x1D
|
||||
X"20", -- 0x1E
|
||||
X"65", -- 0x1F
|
||||
X"69", -- 0x20
|
||||
X"6E", -- 0x21
|
||||
X"65", -- 0x22
|
||||
X"20", -- 0x23
|
||||
X"6C", -- 0x24
|
||||
X"69", -- 0x25
|
||||
X"65", -- 0x26
|
||||
X"62", -- 0x27
|
||||
X"65", -- 0x28
|
||||
X"20", -- 0x29
|
||||
X"4B", -- 0x2A
|
||||
X"61", -- 0x2B
|
||||
X"74", -- 0x2C
|
||||
X"7A", -- 0x2D
|
||||
X"65", -- 0x2E
|
||||
X"20", -- 0x2F
|
||||
X"21", -- 0x30
|
||||
X"21", -- 0x31
|
||||
X"21", -- 0x32
|
||||
X"0D", -- 0x33
|
||||
X"0A", -- 0x34
|
||||
X"00", -- 0x35
|
||||
X"00", -- 0x36
|
||||
X"00", -- 0x37
|
||||
X"00", -- 0x38
|
||||
X"00", -- 0x39
|
||||
X"00", -- 0x3A
|
||||
X"00", -- 0x3B
|
||||
X"00", -- 0x3C
|
||||
X"00", -- 0x3D
|
||||
X"00", -- 0x3E
|
||||
X"00", -- 0x3F
|
||||
X"00", -- 0x40
|
||||
X"00", -- 0x41
|
||||
X"00", -- 0x42
|
||||
X"00", -- 0x43
|
||||
X"00", -- 0x44
|
||||
X"00", -- 0x45
|
||||
X"00", -- 0x46
|
||||
X"00", -- 0x47
|
||||
X"00", -- 0x48
|
||||
X"00", -- 0x49
|
||||
X"00", -- 0x4A
|
||||
X"00", -- 0x4B
|
||||
X"00", -- 0x4C
|
||||
X"00", -- 0x4D
|
||||
X"00", -- 0x4E
|
||||
X"00", -- 0x4F
|
||||
X"00", -- 0x50
|
||||
X"00", -- 0x51
|
||||
X"00", -- 0x52
|
||||
X"00", -- 0x53
|
||||
X"00", -- 0x54
|
||||
X"00", -- 0x55
|
||||
X"00", -- 0x56
|
||||
X"00", -- 0x57
|
||||
X"00", -- 0x58
|
||||
X"00", -- 0x59
|
||||
X"00", -- 0x5A
|
||||
X"00", -- 0x5B
|
||||
X"00", -- 0x5C
|
||||
X"00", -- 0x5D
|
||||
X"00", -- 0x5E
|
||||
X"00", -- 0x5F
|
||||
X"00", -- 0x60
|
||||
X"00", -- 0x61
|
||||
X"00", -- 0x62
|
||||
X"00", -- 0x63
|
||||
X"00", -- 0x64
|
||||
X"00", -- 0x65
|
||||
X"00", -- 0x66
|
||||
X"00", -- 0x67
|
||||
X"00", -- 0x68
|
||||
X"00", -- 0x69
|
||||
X"00", -- 0x6A
|
||||
X"00", -- 0x6B
|
||||
X"00", -- 0x6C
|
||||
X"00", -- 0x6D
|
||||
X"00", -- 0x6E
|
||||
X"00", -- 0x6F
|
||||
X"00", -- 0x70
|
||||
X"00", -- 0x71
|
||||
X"00", -- 0x72
|
||||
X"00", -- 0x73
|
||||
X"00", -- 0x74
|
||||
X"00", -- 0x75
|
||||
X"00", -- 0x76
|
||||
X"00", -- 0x77
|
||||
X"00", -- 0x78
|
||||
X"00", -- 0x79
|
||||
X"00", -- 0x7A
|
||||
X"00", -- 0x7B
|
||||
X"00", -- 0x7C
|
||||
X"00", -- 0x7D
|
||||
X"00", -- 0x7E
|
||||
X"00", -- 0x7F
|
||||
X"00", -- 0x80
|
||||
X"00", -- 0x81
|
||||
X"00", -- 0x82
|
||||
X"00", -- 0x83
|
||||
X"00", -- 0x84
|
||||
X"00", -- 0x85
|
||||
X"00", -- 0x86
|
||||
X"00", -- 0x87
|
||||
X"00", -- 0x88
|
||||
X"00", -- 0x89
|
||||
X"00", -- 0x8A
|
||||
X"00", -- 0x8B
|
||||
X"00", -- 0x8C
|
||||
X"00", -- 0x8D
|
||||
X"00", -- 0x8E
|
||||
X"00", -- 0x8F
|
||||
X"00", -- 0x90
|
||||
X"00", -- 0x91
|
||||
X"00", -- 0x92
|
||||
X"00", -- 0x93
|
||||
X"00", -- 0x94
|
||||
X"00", -- 0x95
|
||||
X"00", -- 0x96
|
||||
X"00", -- 0x97
|
||||
X"00", -- 0x98
|
||||
X"00", -- 0x99
|
||||
X"00", -- 0x9A
|
||||
X"00", -- 0x9B
|
||||
X"00", -- 0x9C
|
||||
X"00", -- 0x9D
|
||||
X"00", -- 0x9E
|
||||
X"00", -- 0x9F
|
||||
X"00", -- 0xA0
|
||||
X"00", -- 0xA1
|
||||
X"00", -- 0xA2
|
||||
X"00", -- 0xA3
|
||||
X"00", -- 0xA4
|
||||
X"00", -- 0xA5
|
||||
X"00", -- 0xA6
|
||||
X"00", -- 0xA7
|
||||
X"00", -- 0xA8
|
||||
X"00", -- 0xA9
|
||||
X"00", -- 0xAA
|
||||
X"00", -- 0xAB
|
||||
X"00", -- 0xAC
|
||||
X"00", -- 0xAD
|
||||
X"00", -- 0xAE
|
||||
X"00", -- 0xAF
|
||||
X"00", -- 0xB0
|
||||
X"00", -- 0xB1
|
||||
X"00", -- 0xB2
|
||||
X"00", -- 0xB3
|
||||
X"00", -- 0xB4
|
||||
X"00", -- 0xB5
|
||||
X"00", -- 0xB6
|
||||
X"00", -- 0xB7
|
||||
X"00", -- 0xB8
|
||||
X"00", -- 0xB9
|
||||
X"00", -- 0xBA
|
||||
X"00", -- 0xBB
|
||||
X"00", -- 0xBC
|
||||
X"00", -- 0xBD
|
||||
X"00", -- 0xBE
|
||||
X"00", -- 0xBF
|
||||
X"00", -- 0xC0
|
||||
X"00", -- 0xC1
|
||||
X"00", -- 0xC2
|
||||
X"00", -- 0xC3
|
||||
X"00", -- 0xC4
|
||||
X"00", -- 0xC5
|
||||
X"00", -- 0xC6
|
||||
X"00", -- 0xC7
|
||||
X"00", -- 0xC8
|
||||
X"00", -- 0xC9
|
||||
X"00", -- 0xCA
|
||||
X"00", -- 0xCB
|
||||
X"00", -- 0xCC
|
||||
X"00", -- 0xCD
|
||||
X"00", -- 0xCE
|
||||
X"00", -- 0xCF
|
||||
X"00", -- 0xD0
|
||||
X"00", -- 0xD1
|
||||
X"00", -- 0xD2
|
||||
X"00", -- 0xD3
|
||||
X"00", -- 0xD4
|
||||
X"00", -- 0xD5
|
||||
X"00", -- 0xD6
|
||||
X"00", -- 0xD7
|
||||
X"00", -- 0xD8
|
||||
X"00", -- 0xD9
|
||||
X"00", -- 0xDA
|
||||
X"00", -- 0xDB
|
||||
X"00", -- 0xDC
|
||||
X"00", -- 0xDD
|
||||
X"00", -- 0xDE
|
||||
X"00", -- 0xDF
|
||||
X"00", -- 0xE0
|
||||
X"00", -- 0xE1
|
||||
X"00", -- 0xE2
|
||||
X"00", -- 0xE3
|
||||
X"00", -- 0xE4
|
||||
X"00", -- 0xE5
|
||||
X"00", -- 0xE6
|
||||
X"00", -- 0xE7
|
||||
X"00", -- 0xE8
|
||||
X"00", -- 0xE9
|
||||
X"00", -- 0xEA
|
||||
X"00", -- 0xEB
|
||||
X"00", -- 0xEC
|
||||
X"00", -- 0xED
|
||||
X"00", -- 0xEE
|
||||
X"00", -- 0xEF
|
||||
X"00", -- 0xF0
|
||||
X"00", -- 0xF1
|
||||
X"00", -- 0xF2
|
||||
X"00", -- 0xF3
|
||||
X"00", -- 0xF4
|
||||
X"00", -- 0xF5
|
||||
X"00", -- 0xF6
|
||||
X"00", -- 0xF7
|
||||
X"00", -- 0xF8
|
||||
X"00", -- 0xF9
|
||||
X"00", -- 0xFA
|
||||
X"00", -- 0xFB
|
||||
X"00", -- 0xFC
|
||||
X"00", -- 0xFD
|
||||
X"00", -- 0xFE
|
||||
X"00" -- 0xFF
|
||||
);
|
||||
|
||||
signal jtag_ld_clk : STD_LOGIC;
|
||||
signal jtag_ld_we : STD_LOGIC;
|
||||
signal jtag_ld_addr : dmem_addr_t;
|
||||
signal jtag_ld_dout : dmem_data_t;
|
||||
signal jtag_ld_din : dmem_data_t;
|
||||
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
||||
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
||||
signal user_regi, user_rego : unsigned (15 downto 0);
|
||||
constant id : unsigned (15 downto 0) := X"BEEF";
|
||||
|
||||
begin
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Virtex-4: JTAG Loader
|
||||
--------------------------------------------------------------------------
|
||||
i00_BUFG : BUFG
|
||||
port map
|
||||
(
|
||||
O => bs_clk1,
|
||||
I => bs_clk0
|
||||
);
|
||||
|
||||
i01_BUFG : BUFG
|
||||
port map
|
||||
(
|
||||
O => bs_update1,
|
||||
I => bs_update0
|
||||
);
|
||||
|
||||
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
|
||||
generic map
|
||||
(
|
||||
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
||||
)
|
||||
port map
|
||||
(
|
||||
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
||||
DRCK => bs_clk0, -- Data register output for USER functions
|
||||
RESET => bs_rst, -- Reset output from TAP controller
|
||||
SEL => bs_sel, -- USER active output
|
||||
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
||||
TDI => bs_tdi, -- TDI output from TAP controller
|
||||
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
||||
TDO => bs_tdo -- Data input for USER function
|
||||
);
|
||||
|
||||
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-dmem_data_t'length+1);
|
||||
jtag_ld_din <= user_regi(dmem_data_t'left downto 0);
|
||||
jtag_ld_clk <= bs_update1;
|
||||
jtag_ld_we <= bs_sel;
|
||||
|
||||
sipo:
|
||||
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
||||
begin
|
||||
if bs_rst = '1' then
|
||||
user_regi <= (others => '0');
|
||||
elsif rising_edge(bs_clk1) then
|
||||
if bs_shift = '1' then
|
||||
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
piso:
|
||||
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
||||
begin
|
||||
bs_tdo <= user_rego(0);
|
||||
if bs_rst = '1' then
|
||||
user_rego <= (others => '0');
|
||||
elsif rising_edge(bs_clk1) then
|
||||
if bs_shift = '1' then
|
||||
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
||||
else
|
||||
user_rego <= (user_rego'left downto dmem_data_t'length => '0') & jtag_ld_dout;
|
||||
-- user_rego <= id;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- ROM Read/Write
|
||||
--------------------------------------------------------------------------
|
||||
PROM_READ:
|
||||
process(clk, ce)
|
||||
begin
|
||||
if rising_edge(clk) and ce = '1' then
|
||||
dout <= xmem_rom(to_integer(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
PROM_WRITE:
|
||||
process(jtag_ld_clk, jtag_ld_we)
|
||||
begin
|
||||
if rising_edge(jtag_ld_clk) then
|
||||
if jtag_ld_we = '1' then
|
||||
xmem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
|
||||
else
|
||||
jtag_ld_dout <= xmem_rom(to_integer(jtag_ld_addr));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end loadable;
|
||||
@@ -0,0 +1,147 @@
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 13:58:47 10/15/2005
|
||||
-- Design Name: vga_ctrl_top
|
||||
-- Module Name: tb_vga_ctrl.vhd
|
||||
-- Project Name: vga_ctrl
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- VHDL Test Bench Created by ISE for module: vga_ctrl_top
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
-- Notes:
|
||||
-- This testbench has been automatically generated using types std_logic and
|
||||
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
|
||||
-- that these types always be used for the top-level I/O of a design in order
|
||||
-- to guarantee that the testbench will bind correctly to the post-implementation
|
||||
-- simulation model.
|
||||
--------------------------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
use work.vga_types.all;
|
||||
|
||||
ENTITY tb_vga_ctrl_vhd IS
|
||||
END tb_vga_ctrl_vhd;
|
||||
|
||||
ARCHITECTURE behavior OF tb_vga_ctrl_vhd IS
|
||||
|
||||
-- Component Declaration for the Unit Under Test (UUT)
|
||||
COMPONENT vga_ctrl_top
|
||||
GENERIC
|
||||
(
|
||||
sys_freq : real;
|
||||
fifo_depth : integer;
|
||||
tsvga : vga_timespec_t
|
||||
);
|
||||
PORT
|
||||
(
|
||||
sys_rstn_in : IN std_logic;
|
||||
sys_clk_in : IN std_logic;
|
||||
sys_vga_red : OUT unsigned(7 downto 0);
|
||||
sys_vga_green : OUT unsigned(7 downto 0);
|
||||
sys_vga_blue : OUT unsigned(7 downto 0);
|
||||
sys_vga_blank_n : OUT std_logic;
|
||||
sys_vga_sync_n : OUT std_logic;
|
||||
sys_vga_hsync : OUT std_logic;
|
||||
sys_vga_vsync : OUT std_logic;
|
||||
sys_vga_clk : OUT std_logic;
|
||||
sys_dip : in unsigned(7 downto 0);
|
||||
sys_btn : in unsigned(4 downto 0);
|
||||
sys_led : out unsigned(8 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
--Constants
|
||||
constant PERIOD : time := 9.9304865938430983118172790466733 ns;
|
||||
|
||||
--Inputs
|
||||
SIGNAL sys_rstn_in : std_logic := '0';
|
||||
SIGNAL sys_clk_in : std_logic := '0';
|
||||
SIGNAL sys_color_en : unsigned(2 downto 0) := (others => '0');
|
||||
SIGNAL sys_dip : unsigned(7 downto 0) := (others => '0');
|
||||
SIGNAL sys_btn : unsigned(4 downto 0) := (others => '0');
|
||||
|
||||
--Outputs
|
||||
SIGNAL sys_vga_red : unsigned(7 downto 0);
|
||||
SIGNAL sys_vga_green : unsigned(7 downto 0);
|
||||
SIGNAL sys_vga_blue : unsigned(7 downto 0);
|
||||
SIGNAL sys_vga_blank_n : std_logic;
|
||||
SIGNAL sys_vga_sync_n : std_logic;
|
||||
SIGNAL sys_vga_hsync : std_logic;
|
||||
SIGNAL sys_vga_vsync : std_logic;
|
||||
SIGNAL sys_vga_clk : std_logic;
|
||||
SIGNAL sys_led : unsigned(8 downto 0);
|
||||
constant f_sys : real := 100.0;
|
||||
constant f_vga : real := 130.0;
|
||||
-- SIGNAL test_M : natural := VGA_FREQ_M(f_sys, f_vga);
|
||||
-- SIGNAL test_D : natural := VGA_FREQ_D(f_sys, f_vga);
|
||||
|
||||
BEGIN
|
||||
|
||||
-- Instantiate the Unit Under Test (UUT)
|
||||
uut: vga_ctrl_top
|
||||
GENERIC MAP
|
||||
(
|
||||
sys_freq => f_sys,
|
||||
fifo_depth => 2048,
|
||||
tsvga => ts_vga_testbench
|
||||
)
|
||||
PORT MAP(
|
||||
sys_rstn_in => sys_rstn_in,
|
||||
sys_clk_in => sys_clk_in,
|
||||
sys_vga_red => sys_vga_red,
|
||||
sys_vga_green => sys_vga_green,
|
||||
sys_vga_blue => sys_vga_blue,
|
||||
sys_vga_blank_n => sys_vga_blank_n,
|
||||
sys_vga_sync_n => sys_vga_sync_n,
|
||||
sys_vga_hsync => sys_vga_hsync,
|
||||
sys_vga_vsync => sys_vga_vsync,
|
||||
sys_vga_clk => sys_vga_clk,
|
||||
sys_dip => sys_dip,
|
||||
sys_btn => sys_btn,
|
||||
sys_led => sys_led
|
||||
);
|
||||
|
||||
tb_clk : PROCESS
|
||||
BEGIN
|
||||
sys_clk_in <= not sys_clk_in;
|
||||
wait for PERIOD/2;
|
||||
END PROCESS;
|
||||
|
||||
tb : PROCESS
|
||||
BEGIN
|
||||
|
||||
-- Wait 100 ns for global reset to finish
|
||||
wait for 20*PERIOD;
|
||||
sys_rstn_in <= '1';
|
||||
|
||||
wait for PERIOD;
|
||||
sys_dip <= X"AA";
|
||||
|
||||
wait for PERIOD;
|
||||
sys_color_en <= "100";
|
||||
|
||||
wait for 10*PERIOD;
|
||||
sys_color_en <= "000";
|
||||
|
||||
-- Wait 100 ns for global reset to finish
|
||||
wait for 100 ns;
|
||||
|
||||
-- Place stimulus here
|
||||
|
||||
wait; -- will wait forever
|
||||
END PROCESS;
|
||||
|
||||
END;
|
||||
@@ -0,0 +1,394 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 11:25:45 10/15/05
|
||||
-- Design Name:
|
||||
-- Module Name: vga_ctrl_top - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
use work.vga_types.all;
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
entity vga_ctrl_top is
|
||||
Generic
|
||||
(
|
||||
sys_freq : real := 100.0;
|
||||
fifo_depth : integer := 2048;
|
||||
tsvga : vga_timespec_t := ts_vga_1280_1024_72
|
||||
);
|
||||
Port
|
||||
(
|
||||
sys_rstn_in : in std_logic;
|
||||
sys_clk_in : in std_logic;
|
||||
sys_vga_red : out unsigned(7 downto 0);
|
||||
sys_vga_green : out unsigned(7 downto 0);
|
||||
sys_vga_blue : out unsigned(7 downto 0);
|
||||
sys_vga_blank_n : out std_logic;
|
||||
sys_vga_sync_n : out std_logic;
|
||||
sys_vga_hsync : out std_logic;
|
||||
sys_vga_vsync : out std_logic;
|
||||
sys_vga_clk : out std_logic;
|
||||
-- Buttons and LEDs
|
||||
sys_btn : in unsigned(4 downto 0);
|
||||
sys_dip : in unsigned(7 downto 0);
|
||||
sys_led : out unsigned(8 downto 0)
|
||||
);
|
||||
end vga_ctrl_top;
|
||||
|
||||
architecture Behavioral of vga_ctrl_top is
|
||||
|
||||
-- System signal
|
||||
signal rst : std_logic;
|
||||
signal clk : std_logic;
|
||||
signal vga_rst : std_logic;
|
||||
signal vga_clk : std_logic;
|
||||
signal vga_ready : std_logic;
|
||||
|
||||
-- Timing
|
||||
signal scan_rdy : std_logic;
|
||||
signal scan_rdy_h : std_logic;
|
||||
signal scan_rdy_v : std_logic;
|
||||
signal vga_scan_x : std_logic;
|
||||
signal vga_scan_y : std_logic;
|
||||
signal hsync : std_logic;
|
||||
signal vsync : std_logic;
|
||||
|
||||
signal src_pos_x : natural range 0 to tsvga.ts_h.ncyc_scan-1;
|
||||
signal src_pos_y : natural range 0 to tsvga.ts_v.ncyc_scan-1;
|
||||
signal vga_pos_x : natural range 0 to tsvga.ts_h.ncyc_scan-1;
|
||||
signal vga_pos_y : natural range 0 to tsvga.ts_v.ncyc_scan-1;
|
||||
|
||||
-- Line buffers
|
||||
signal color_w : color_t;
|
||||
signal vga_color : color_t;
|
||||
signal color_we : std_logic;
|
||||
signal fifo_full : std_logic;
|
||||
signal fifo_almost_full : std_logic;
|
||||
signal scan_enable : std_logic;
|
||||
signal src_enable : std_logic;
|
||||
signal src_cnt_en : std_logic;
|
||||
signal char_draw_en : std_logic;
|
||||
signal cg_en : std_logic;
|
||||
signal cpu_color : color_t;
|
||||
|
||||
-- CPU signals
|
||||
signal cpu_rst : std_logic;
|
||||
signal cpu_ce : std_logic;
|
||||
signal cpu_int_in : std_logic;
|
||||
signal cpu_int_ack : std_logic;
|
||||
signal cpu_we : std_logic;
|
||||
signal cpu_re : std_logic;
|
||||
signal cpu_io_sel : std_logic;
|
||||
signal cpu_din : dmem_data_t;
|
||||
signal cpu_dout : dmem_data_t;
|
||||
signal cpu_addr : dmem_addr_t;
|
||||
signal cpu_xrom_data : dmem_data_t;
|
||||
|
||||
signal cg_ready : std_logic;
|
||||
signal cg_clr_screen : std_logic;
|
||||
signal cg_clr_line : std_logic;
|
||||
signal cg_ascii_data : dmem_data_t;
|
||||
signal cg_ascii_data_we : std_logic;
|
||||
signal cg_ascii_posy_we : std_logic;
|
||||
signal cg_ascii_posx_we : std_logic;
|
||||
|
||||
signal cpu_led : dmem_data_t;
|
||||
signal cpu_red : dmem_data_t;
|
||||
signal cpu_green : dmem_data_t;
|
||||
signal cpu_blue : dmem_data_t;
|
||||
|
||||
begin
|
||||
|
||||
inst_vga_backend: entity work.vga_backend
|
||||
GENERIC MAP
|
||||
(
|
||||
sys_freq => sys_freq,
|
||||
fifo_depth => fifo_depth,
|
||||
tsvga => tsvga
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
sys_rst => vga_rst,
|
||||
sys_clk => clk,
|
||||
vga_ready => vga_ready,
|
||||
color_in => color_w,
|
||||
color_fifo_we => color_we,
|
||||
color_fifo_full => fifo_full,
|
||||
color_fifo_afull => fifo_almost_full,
|
||||
direct_color_in => cpu_color,
|
||||
direct_draw_en => char_draw_en,
|
||||
stat_hsync => hsync,
|
||||
stat_vsync => vsync,
|
||||
stat_hready => scan_rdy_h,
|
||||
stat_vready => scan_rdy_v,
|
||||
stat_hscan => vga_scan_x,
|
||||
stat_vscan => vga_scan_y,
|
||||
stat_hpos => vga_pos_x,
|
||||
stat_vpos => vga_pos_y,
|
||||
vga_clk_out => vga_clk,
|
||||
vga_color_out => vga_color,
|
||||
vga_blank_n => sys_vga_blank_n,
|
||||
vga_sync_n => sys_vga_sync_n,
|
||||
vga_hsync => sys_vga_hsync,
|
||||
vga_vsync => sys_vga_vsync
|
||||
|
||||
);
|
||||
|
||||
inst_char_gen : entity work.char_gen
|
||||
GENERIC MAP
|
||||
(
|
||||
tsvga => tsvga,
|
||||
CHARACTER_SCALE => 1,
|
||||
CHAR_ROM_SIZE_X => 8, -- Pixels
|
||||
CHAR_ROM_SIZE_Y => 16, -- Pixels
|
||||
CHAR_ROM_DEPTH => 256, -- Chars
|
||||
MAX_CHAR_PER_LINE => 80, -- Chars
|
||||
MAX_LINE_PER_FRAME => 32, -- Chars
|
||||
CHAR_SPACING_X => 0, -- Pixels
|
||||
CHAR_SPACING_Y => 0, -- Pixels
|
||||
SCREEN_OFFSET_X => 16, -- Pixels
|
||||
SCREEN_OFFSET_Y => 16 -- Pixels
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
sys_clk => clk,
|
||||
vga_clk => vga_clk,
|
||||
ce => cg_en,
|
||||
frame_pulse => scan_rdy,
|
||||
clr_screen => cg_clr_screen,
|
||||
clr_line => cg_clr_line,
|
||||
ascii_data => cg_ascii_data,
|
||||
ascii_data_we => cg_ascii_data_we,
|
||||
ascii_posy_we => cg_ascii_posy_we,
|
||||
ascii_posx_we => cg_ascii_posx_we,
|
||||
ready => cg_ready,
|
||||
pos_x => vga_pos_x,
|
||||
pos_y => vga_pos_y,
|
||||
char_draw_en => char_draw_en
|
||||
);
|
||||
|
||||
inst_cpu_embedded: entity work.cpu_embedded
|
||||
PORT MAP(
|
||||
rst => cpu_rst,
|
||||
clk => clk,
|
||||
ce => cpu_ce,
|
||||
int_in => cpu_int_in,
|
||||
int_ack => cpu_int_ack,
|
||||
xmem_we => cpu_we,
|
||||
xmem_re => cpu_re,
|
||||
xmem_din => cpu_din,
|
||||
xmem_dout => cpu_dout,
|
||||
xmem_addr => cpu_addr,
|
||||
io_sel => cpu_io_sel
|
||||
);
|
||||
|
||||
inst_xrom: entity work.xrom
|
||||
PORT MAP(
|
||||
clk => clk,
|
||||
ce => cpu_ce,
|
||||
addr => cpu_addr,
|
||||
dout => cpu_xrom_data
|
||||
);
|
||||
|
||||
---------------------------------------------------------------------------------------------
|
||||
rst <= not vga_ready;
|
||||
vga_rst <= not sys_rstn_in;
|
||||
|
||||
-- clk <= vga_clk;
|
||||
clk <= sys_clk_in;
|
||||
|
||||
scan_rdy <= scan_rdy_h and scan_rdy_v;
|
||||
|
||||
sys_vga_clk <= vga_clk;
|
||||
sys_vga_red <= vga_color(r);
|
||||
sys_vga_green <= vga_color(g);
|
||||
sys_vga_blue <= vga_color(b);
|
||||
|
||||
cg_en <= vga_scan_x and vga_scan_y;
|
||||
cpu_ce <= '1';
|
||||
|
||||
---------------------------------------------------------------------------------------------
|
||||
led_out: process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
sys_led <= '0' & cpu_led;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------------------------------------------
|
||||
cpu_reg_read:
|
||||
process(clk, cpu_io_sel, cpu_xrom_data)
|
||||
variable reg : dmem_data_t;
|
||||
begin
|
||||
|
||||
if rising_edge(clk) then
|
||||
case cpu_addr is
|
||||
when X"00" => -- 00
|
||||
reg := "000" & unsigned(sys_btn(4 downto 0));
|
||||
when X"01" => -- 01
|
||||
reg := cpu_led;
|
||||
when X"05" => -- 05
|
||||
reg := unsigned(sys_dip);
|
||||
when X"0B" =>
|
||||
reg := "000000" & cg_ready & vga_ready;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
cpu_din <= cpu_xrom_data;
|
||||
if cpu_io_sel = '1' then
|
||||
cpu_din <= reg;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
cpu_reg_write:
|
||||
process(rst, clk)
|
||||
variable addr : unsigned(dmem_addr_t'length-1 downto 0);
|
||||
begin
|
||||
if (rst = '1') then
|
||||
cpu_led <= (others => '0');
|
||||
cg_ascii_data <= (others => '0');
|
||||
cg_ascii_posy_we <= '0';
|
||||
cg_ascii_posx_we <= '0';
|
||||
cg_ascii_data_we <= '0';
|
||||
cg_clr_line <= '0';
|
||||
cg_clr_screen <= '0';
|
||||
cpu_red <= X"80";
|
||||
cpu_green <= X"80";
|
||||
cpu_blue <= X"80";
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
cg_ascii_posy_we <= '0';
|
||||
cg_ascii_posx_we <= '0';
|
||||
cg_ascii_data_we <= '0';
|
||||
cg_clr_line <= '0';
|
||||
cg_clr_screen <= '0';
|
||||
addr := cpu_addr;
|
||||
if cpu_we = '1' then
|
||||
if cpu_io_sel = '1' then
|
||||
case addr is
|
||||
when X"01" => -- 01
|
||||
cpu_led <= cpu_dout;
|
||||
when X"02" => -- 04
|
||||
cpu_red <= cpu_dout;
|
||||
when X"03" => -- 04
|
||||
cpu_green <= cpu_dout;
|
||||
when X"04" => -- 04
|
||||
cpu_blue <= cpu_dout;
|
||||
when X"08" => -- 08
|
||||
cg_ascii_data <= cpu_dout;
|
||||
cg_ascii_posx_we <= '1';
|
||||
when X"09" => -- 09
|
||||
cg_ascii_data <= cpu_dout;
|
||||
cg_ascii_posy_we <= '1';
|
||||
when X"0A" => -- 0A
|
||||
cg_ascii_data <= cpu_dout;
|
||||
cg_ascii_data_we <= '1';
|
||||
when X"0B" => -- 0B
|
||||
cg_clr_screen <= cpu_dout(0);
|
||||
cg_clr_line <= cpu_dout(1);
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------------------------------------------
|
||||
--- Test
|
||||
---------------------------------------------------------------------------------------------
|
||||
cpu_start: process (rst, vga_clk)
|
||||
begin
|
||||
if (rst = '1') then
|
||||
cpu_rst <= '1';
|
||||
elsif rising_edge(vga_clk) and scan_rdy = '1' then
|
||||
cpu_rst <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
scan_start: process (rst, clk)
|
||||
begin
|
||||
if (rst = '1') then
|
||||
scan_enable <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
scan_enable <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
color_sel: process (vga_clk)
|
||||
begin
|
||||
if rising_edge(vga_clk) and scan_rdy = '1' then
|
||||
cpu_color <= (cpu_red, cpu_green, cpu_blue);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
color_we <= scan_enable and src_enable and not fifo_full;
|
||||
|
||||
src_inc_reg: process (rst, clk)
|
||||
begin
|
||||
if (rst = '1') then
|
||||
src_enable <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if fifo_full = '1' then
|
||||
src_enable <= '0';
|
||||
elsif fifo_almost_full = '0' then
|
||||
src_enable <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
color_ctrl: process (rst, clk)
|
||||
variable enable : std_logic;
|
||||
begin
|
||||
if (rst = '1') then
|
||||
src_pos_x <= 0;
|
||||
src_pos_y <= 0;
|
||||
elsif rising_edge(clk) then
|
||||
if color_we = '1' then
|
||||
if src_pos_x < tsvga.ts_h.ncyc_scan-1 then
|
||||
src_pos_x <= src_pos_x + 1;
|
||||
else
|
||||
src_pos_x <= 0;
|
||||
if src_pos_y < tsvga.ts_v.ncyc_scan-1 then
|
||||
src_pos_y <= src_pos_y + 1;
|
||||
else
|
||||
src_pos_y <= 0;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
color_gen: process (src_pos_x, src_pos_y)
|
||||
begin
|
||||
color_w <= (X"00", X"00", X"00");
|
||||
if src_pos_y = 0 then
|
||||
color_w <= (X"00", X"FF", X"00");
|
||||
elsif src_pos_y = (tsvga.ts_v.ncyc_scan-1) then
|
||||
color_w <= (X"00", X"FF", X"00");
|
||||
elsif src_pos_x = 0 then
|
||||
color_w <= (X"FF", X"00", X"00");
|
||||
elsif src_pos_x = (tsvga.ts_h.ncyc_scan-1) then
|
||||
color_w <= (X"00", X"00", X"FF");
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
Reference in New Issue
Block a user