Initial revision
Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@939 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
module j1(
|
||||
input sys_clk_i, input sys_rst_i, input [15:0] io_din,
|
||||
output io_rd, output io_wr, output [15:0] io_addr, output [15:0] io_dout);
|
||||
|
||||
wire [15:0] insn;
|
||||
wire [15:0] immediate = { 1'b0, insn[14:0] };
|
||||
|
||||
wire [15:0] ramrd;
|
||||
|
||||
reg [4:0] dsp; // Data stack pointer
|
||||
reg [4:0] _dsp;
|
||||
reg [15:0] st0; // Return stack pointer
|
||||
reg [15:0] _st0;
|
||||
wire _dstkW; // D stack write
|
||||
|
||||
reg [12:0] pc;
|
||||
reg [12:0] _pc;
|
||||
reg [4:0] rsp;
|
||||
reg [4:0] _rsp;
|
||||
reg _rstkW; // R stack write
|
||||
reg [15:0] _rstkD;
|
||||
wire _ramWE; // RAM write enable
|
||||
|
||||
wire [15:0] pc_plus_1;
|
||||
assign pc_plus_1 = pc + 1;
|
||||
|
||||
// The D and R stacks
|
||||
reg [15:0] dstack[0:31];
|
||||
reg [15:0] rstack[0:31];
|
||||
always @(posedge sys_clk_i)
|
||||
begin
|
||||
if (_dstkW)
|
||||
dstack[_dsp] = st0;
|
||||
if (_rstkW)
|
||||
rstack[_rsp] = _rstkD;
|
||||
end
|
||||
wire [15:0] st1 = dstack[dsp];
|
||||
wire [15:0] rst0 = rstack[rsp];
|
||||
|
||||
// st0sel is the ALU operation. For branch and call the operation
|
||||
// is T, for 0branch it is N. For ALU ops it is loaded from the instruction
|
||||
// field.
|
||||
reg [3:0] st0sel;
|
||||
always @*
|
||||
begin
|
||||
case (insn[14:13])
|
||||
2'b00: st0sel = 0; // ubranch
|
||||
2'b10: st0sel = 0; // call
|
||||
2'b01: st0sel = 1; // 0branch
|
||||
2'b11: st0sel = insn[11:8]; // ALU
|
||||
default: st0sel = 4'bxxxx;
|
||||
endcase
|
||||
end
|
||||
|
||||
`define RAMS 3
|
||||
|
||||
genvar i;
|
||||
|
||||
`define w (16 >> `RAMS)
|
||||
`define w1 (`w - 1)
|
||||
|
||||
generate
|
||||
for (i = 0; i < (1 << `RAMS); i=i+1) begin : ram
|
||||
// RAMB16_S18_S18
|
||||
RAMB16_S2_S2
|
||||
ram(
|
||||
.DIA(0),
|
||||
// .DIPA(0),
|
||||
.DOA(insn[`w*i+`w1:`w*i]),
|
||||
.WEA(0),
|
||||
.ENA(1),
|
||||
.CLKA(sys_clk_i),
|
||||
.ADDRA({_pc}),
|
||||
|
||||
.DIB(st1[`w*i+`w1:`w*i]),
|
||||
// .DIPB(2'b0),
|
||||
.WEB(_ramWE & (_st0[15:14] == 0)),
|
||||
.ENB(|_st0[15:14] == 0),
|
||||
.CLKB(sys_clk_i),
|
||||
.ADDRB(_st0[15:1]),
|
||||
.DOB(ramrd[`w*i+`w1:`w*i]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Compute the new value of T.
|
||||
always @*
|
||||
begin
|
||||
if (insn[15])
|
||||
_st0 = immediate;
|
||||
else
|
||||
case (st0sel)
|
||||
4'b0000: _st0 = st0;
|
||||
4'b0001: _st0 = st1;
|
||||
4'b0010: _st0 = st0 + st1;
|
||||
4'b0011: _st0 = st0 & st1;
|
||||
4'b0100: _st0 = st0 | st1;
|
||||
4'b0101: _st0 = st0 ^ st1;
|
||||
4'b0110: _st0 = ~st0;
|
||||
4'b0111: _st0 = {16{(st1 == st0)}};
|
||||
4'b1000: _st0 = {16{($signed(st1) < $signed(st0))}};
|
||||
4'b1001: _st0 = st1 >> st0[3:0];
|
||||
4'b1010: _st0 = st0 - 1;
|
||||
4'b1011: _st0 = rst0;
|
||||
4'b1100: _st0 = |st0[15:14] ? io_din : ramrd;
|
||||
4'b1101: _st0 = st1 << st0[3:0];
|
||||
4'b1110: _st0 = {rsp, 3'b000, dsp};
|
||||
4'b1111: _st0 = {16{(st1 < st0)}};
|
||||
default: _st0 = 16'hxxxx;
|
||||
endcase
|
||||
end
|
||||
|
||||
wire is_alu = (insn[15:13] == 3'b011);
|
||||
wire is_lit = (insn[15]);
|
||||
|
||||
assign io_rd = (is_alu & (insn[11:8] == 4'hc));
|
||||
assign io_wr = _ramWE;
|
||||
assign io_addr = st0;
|
||||
assign io_dout = st1;
|
||||
|
||||
assign _ramWE = is_alu & insn[5];
|
||||
assign _dstkW = is_lit | (is_alu & insn[7]);
|
||||
|
||||
wire [1:0] dd = insn[1:0]; // D stack delta
|
||||
wire [1:0] rd = insn[3:2]; // R stack delta
|
||||
|
||||
always @*
|
||||
begin
|
||||
if (is_lit) begin // literal
|
||||
_dsp = dsp + 1;
|
||||
_rsp = rsp;
|
||||
_rstkW = 0;
|
||||
_rstkD = _pc;
|
||||
end else if (is_alu) begin
|
||||
_dsp = dsp + {dd[1], dd[1], dd[1], dd};
|
||||
_rsp = rsp + {rd[1], rd[1], rd[1], rd};
|
||||
_rstkW = insn[6];
|
||||
_rstkD = st0;
|
||||
end else begin // jump/call
|
||||
// predicated jump is like DROP
|
||||
if (insn[15:13] == 3'b001) begin
|
||||
_dsp = dsp - 1;
|
||||
end else begin
|
||||
_dsp = dsp;
|
||||
end
|
||||
if (insn[15:13] == 3'b010) begin // call
|
||||
_rsp = rsp + 1;
|
||||
_rstkW = 1;
|
||||
_rstkD = {pc_plus_1[14:0], 1'b0};
|
||||
end else begin
|
||||
_rsp = rsp;
|
||||
_rstkW = 0;
|
||||
_rstkD = _pc;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @*
|
||||
begin
|
||||
if (sys_rst_i)
|
||||
_pc = pc;
|
||||
else
|
||||
if ((insn[15:13] == 3'b000) |
|
||||
((insn[15:13] == 3'b001) & (|st0 == 0)) |
|
||||
(insn[15:13] == 3'b010))
|
||||
_pc = insn[12:0];
|
||||
else if (is_alu & insn[12])
|
||||
_pc = rst0[15:1];
|
||||
else
|
||||
_pc = pc_plus_1;
|
||||
end
|
||||
|
||||
always @(posedge sys_clk_i)
|
||||
begin
|
||||
if (sys_rst_i) begin
|
||||
pc <= 0;
|
||||
dsp <= 0;
|
||||
st0 <= 0;
|
||||
rsp <= 0;
|
||||
end else begin
|
||||
dsp <= _dsp;
|
||||
pc <= _pc;
|
||||
st0 <= _st0;
|
||||
rsp <= _rsp;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // j1
|
||||
@@ -0,0 +1,282 @@
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
entity j1 is
|
||||
Generic
|
||||
(
|
||||
R_STACK_SIZE : natural := 32;
|
||||
D_STACK_SIZE : natural := 32
|
||||
|
||||
);
|
||||
Port
|
||||
(
|
||||
sys_clk_i : in std_logic;
|
||||
sys_rst_i : in std_logic;
|
||||
io_din : in unsigned(15 downto 0);
|
||||
io_rd : out std_logic;
|
||||
io_wr : out std_logic;
|
||||
io_addr : out unsigned(15 downto 0);
|
||||
io_dout : out unsigned(15 downto 0);
|
||||
inst_din : in unsigned(15 downto 0);
|
||||
inst_addr : out unsigned(12 downto 0);
|
||||
data_addr : out unsigned(12 downto 0);
|
||||
data_we : out std_logic;
|
||||
data_en : out std_logic;
|
||||
data_din : in unsigned(15 downto 0);
|
||||
data_dout : out unsigned(15 downto 0)
|
||||
|
||||
);
|
||||
end j1;
|
||||
|
||||
architecture behave of j1 is
|
||||
|
||||
signal insn : unsigned(15 downto 0);
|
||||
signal immediate : unsigned(15 downto 0);
|
||||
signal ramrd : unsigned(15 downto 0);
|
||||
|
||||
signal dsp : unsigned(4 downto 0); -- Data stack pointer (register)
|
||||
signal dsp2 : unsigned(4 downto 0); -- register
|
||||
signal st0 : unsigned(15 downto 0); -- Return stack pointer (register)
|
||||
signal st02 : unsigned(15 downto 0); -- register
|
||||
|
||||
signal dstkW2 : std_logic; -- D stack write
|
||||
|
||||
signal pc : unsigned(12 downto 0); -- register
|
||||
signal pc2 : unsigned(12 downto 0); -- register
|
||||
signal rsp : unsigned(4 downto 0); -- register
|
||||
signal rsp2 : unsigned(4 downto 0); -- register
|
||||
|
||||
signal rstkW2 : std_logic; -- register
|
||||
signal rstkD2 : unsigned(15 downto 0); -- register
|
||||
signal ramWE2 : std_logic; -- RAM write enable
|
||||
|
||||
signal pc_plus_1 : unsigned(15 downto 0);
|
||||
|
||||
type stack_t is array (integer range <>) of unsigned(15 downto 0);
|
||||
|
||||
signal dstack : stack_t(0 to D_STACK_SIZE-1); -- register
|
||||
signal rstack : stack_t(0 to R_STACK_SIZE-1); -- register
|
||||
|
||||
signal st1 : unsigned(15 downto 0);
|
||||
signal rst0 : unsigned(15 downto 0);
|
||||
|
||||
signal st0sel : unsigned(3 downto 0);
|
||||
|
||||
signal is_alu : BOOLEAN;
|
||||
signal is_lit : BOOLEAN;
|
||||
|
||||
signal dd : unsigned(1 downto 0); -- D stack delta
|
||||
signal rd : unsigned(1 downto 0); -- R stack delta
|
||||
|
||||
signal stack_ram_en : std_logic; -- helper for RAM R/W
|
||||
signal stack_ram_we : std_logic; -- helper for RAM R/W
|
||||
|
||||
begin
|
||||
|
||||
-- LINE 25:
|
||||
pc_plus_1 <= ("000" & pc) + 1;
|
||||
|
||||
-- LINE 37:
|
||||
st1 <= dstack(to_integer(dsp));
|
||||
rst0 <= rstack(to_integer(rsp));
|
||||
immediate <= '1' & insn(14 downto 0);
|
||||
|
||||
-- LINE 112:
|
||||
is_alu <= (insn(15 downto 13) = "011");
|
||||
is_lit <= (insn(15) = '1');
|
||||
|
||||
|
||||
-- LINE 115:
|
||||
io_rd <= '1' when (is_alu and (insn(11 downto 8) = X"C")) else '0';
|
||||
io_wr <= ramWE2;
|
||||
io_addr <= st0;
|
||||
io_dout <= st1;
|
||||
ramWE2 <= '1' when (is_alu and (insn(5) = '1')) else '0';
|
||||
dstkW2 <= '1' when (is_lit or (is_alu and insn(7) = '1')) else '0';
|
||||
dd <= insn(1 downto 0);
|
||||
rd <= insn(3 downto 2);
|
||||
|
||||
|
||||
-- LINE 27:
|
||||
-- The D and R stacks
|
||||
proc_d_and_r_stack:
|
||||
process(sys_clk_i)
|
||||
begin
|
||||
if rising_edge(sys_clk_i) then
|
||||
if dstkW2 = '1' then
|
||||
dstack(to_integer(dsp2)) <= st0;
|
||||
end if;
|
||||
if rstkW2 = '1' then
|
||||
rstack(to_integer(rsp2)) <= rstkD2;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- LINE 40:
|
||||
-- st0sel is the ALU operation. For branch and call the operation
|
||||
-- is T, for 0branch it is N. For ALU ops it is loaded from the instruction
|
||||
-- field.
|
||||
|
||||
proc_aluop_sel:
|
||||
process(insn)
|
||||
begin
|
||||
|
||||
|
||||
case insn(14 downto 13) is
|
||||
|
||||
when "00" => st0sel <= "0000";
|
||||
when "10" => st0sel <= "0000";
|
||||
when "01" => st0sel <= "0001";
|
||||
when "11" => st0sel <= insn(11 downto 8);
|
||||
when others => st0sel <= "XXXX";
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
|
||||
-- LINE 55:
|
||||
-- define RAMS outside this module
|
||||
insn <= inst_din;
|
||||
inst_addr <= pc2(12 downto 0);
|
||||
data_en <= not (st02(15) or st02(14));
|
||||
data_we <= ramWE2 and not (st02(15) or st02(14));
|
||||
ramrd <= data_din;
|
||||
data_dout <= st1;
|
||||
data_addr <= st02(13 downto 1);
|
||||
|
||||
|
||||
-- LINE 85:
|
||||
-- Compute the new value of T.
|
||||
proc_alu:
|
||||
process(insn, immediate, st0sel, st0, st1, rst0, rsp, dsp)
|
||||
begin
|
||||
|
||||
if insn(15) = '1' then
|
||||
st02 <= immediate;
|
||||
else
|
||||
case st0sel is
|
||||
|
||||
when "0000" => st02 <= st0;
|
||||
when "0001" => st02 <= st1;
|
||||
when "0010" => st02 <= st0 + st1;
|
||||
when "0011" => st02 <= st0 and st1;
|
||||
when "0100" => st02 <= st0 or st1;
|
||||
when "0101" => st02 <= st0 xor st1;
|
||||
when "0110" => st02 <= not st0;
|
||||
when "0111" =>
|
||||
if st1 = st0 then
|
||||
st02 <= X"FFFF";
|
||||
else
|
||||
st02 <= X"0000";
|
||||
end if;
|
||||
|
||||
when "1000" =>
|
||||
if signed(st1) < signed(st0) then
|
||||
st02 <= X"FFFF";
|
||||
else
|
||||
st02 <= X"0000";
|
||||
end if;
|
||||
|
||||
when "1001" => st02 <= st1 srl to_integer(st0(3 downto 0));
|
||||
when "1010" => st02 <= st0 - 1;
|
||||
when "1011" => st02 <= rst0;
|
||||
when "1100" =>
|
||||
if st0(15) = '1' or st0(14) = '1' then -- LINE 104: ????
|
||||
st02 <= io_din;
|
||||
else
|
||||
st02 <= ramrd;
|
||||
end if;
|
||||
|
||||
when "1101" => st02 <= st1 sll to_integer(st0(3 downto 0));
|
||||
when "1110" => st02 <= "000" & rsp & "000" & dsp; -- LINE 106: ????
|
||||
when "1111" =>
|
||||
if st1 < st0 then
|
||||
st02 <= X"FFFF";
|
||||
else
|
||||
st02 <= X"0000";
|
||||
end if;
|
||||
when others => st02 <= "XXXXXXXXXXXXXXXX";
|
||||
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- LINE 126:
|
||||
proc_stack_ctrl:
|
||||
process(is_lit, is_alu, pc2, dd, rd, insn, st0, pc_plus_1, rsp, dsp)
|
||||
begin
|
||||
if is_lit then -- literal
|
||||
dsp2 <= dsp + 1;
|
||||
rsp2 <= rsp;
|
||||
rstkW2 <= '0';
|
||||
rstkD2 <= "000" & pc2;
|
||||
elsif is_alu then
|
||||
dsp2 <= dsp + (dd(1) & dd(1) & dd(1) & dd);
|
||||
rsp2 <= rsp + (rd(1) & rd(1) & rd(1) & rd);
|
||||
rstkW2 <= insn(6);
|
||||
rstkD2 <= st0;
|
||||
else -- jump/call
|
||||
-- predicated jump is like DROP
|
||||
if insn(15 downto 13) = "001" then
|
||||
dsp2 <= dsp - 1;
|
||||
else
|
||||
dsp2 <= dsp; -- *default
|
||||
end if;
|
||||
if insn(15 downto 13) = "010" then -- call
|
||||
rsp2 <= rsp + 1;
|
||||
rstkW2 <= '1';
|
||||
rstkD2 <= pc_plus_1(14 downto 0) & '0';
|
||||
else
|
||||
rsp2 <= rsp; -- *default
|
||||
rstkW2 <= '0'; -- *default
|
||||
rstkD2 <= "000" & pc2; -- *default
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- LINE 157:
|
||||
proc_pc:
|
||||
process(sys_rst_i, is_alu, insn, pc, st0, rst0, pc_plus_1)
|
||||
begin
|
||||
|
||||
if sys_rst_i = '1' then
|
||||
pc2 <= pc;
|
||||
else
|
||||
if ((insn(15 downto 13) = "000")
|
||||
or ((insn(15 downto 13) = "001")
|
||||
and (st0 = X"0000"))
|
||||
or (insn(15 downto 13) = "010")) then
|
||||
pc2 <= insn(12 downto 0);
|
||||
elsif is_alu and (insn(12) = '1') then -- return
|
||||
pc2 <= rst0(13 downto 1); -- LINE 167: ????
|
||||
else
|
||||
pc2 <= pc_plus_1(12 downto 0); -- LINE 169: truncation ????
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- LINE 172:
|
||||
proc_next:
|
||||
process(sys_clk_i)
|
||||
begin
|
||||
|
||||
if rising_edge(sys_clk_i) then
|
||||
if sys_rst_i = '1' then
|
||||
pc <= (others => '0');
|
||||
dsp <= (others => '0');
|
||||
st0 <= (others => '0');
|
||||
rsp <= (others => '0');
|
||||
else
|
||||
dsp <= dsp2;
|
||||
pc <= pc2;
|
||||
st0 <= st02;
|
||||
rsp <= rsp2;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behave;
|
||||
@@ -0,0 +1,84 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: Generic RAM. Infers BlockRAM for Xilinx
|
||||
-- This file: On-chip RAM
|
||||
--
|
||||
-- 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;
|
||||
|
||||
entity ram_2c_2r_2w is
|
||||
Generic
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
Port (
|
||||
clka : in STD_LOGIC;
|
||||
clkb : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_b : in STD_LOGIC;
|
||||
addr_a : in unsigned (addr_width-1 downto 0);
|
||||
addr_b : in unsigned (addr_width-1 downto 0);
|
||||
din_a : in unsigned (data_width-1 downto 0);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
end ram_2c_2r_2w;
|
||||
|
||||
architecture Behavioral of ram_2c_2r_2w is
|
||||
|
||||
constant depth : integer := 2**addr_width;
|
||||
type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0);
|
||||
shared variable RAM : RAMtype;
|
||||
|
||||
begin
|
||||
|
||||
process (clka)
|
||||
begin
|
||||
if clka'event and clka = '1' then
|
||||
if en_a = '1' then
|
||||
if we_a = '1' then
|
||||
RAM(to_integer(addr_a)) := din_a;
|
||||
end if;
|
||||
dout_a <= RAM(to_integer(addr_a));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (clkb)
|
||||
begin
|
||||
if clkb'event and clkb = '1' then
|
||||
if en_b = '1' then
|
||||
if we_b = '1' then
|
||||
RAM(to_integer(addr_b)) := din_b;
|
||||
end if;
|
||||
dout_b <= RAM(to_integer(addr_b));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end Behavioral;
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: testbench for embedded cpu with 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 std.textio.all; -- Imports the standard textio package.
|
||||
|
||||
library work;
|
||||
|
||||
ENTITY tb_j1 IS
|
||||
END tb_j1;
|
||||
|
||||
ARCHITECTURE behavior OF tb_j1 IS
|
||||
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
|
||||
-- Inputs
|
||||
signal sys_clk_i : std_logic := '0';
|
||||
signal sys_rst_i : std_logic := '1';
|
||||
signal io_din : unsigned(15 downto 0) := (others => '0');
|
||||
signal inst_din : unsigned(15 downto 0) := (others => '0');
|
||||
signal data_din : unsigned(15 downto 0) := (others => '0');
|
||||
|
||||
-- Outputs
|
||||
signal io_rd : std_logic;
|
||||
signal io_wr : std_logic;
|
||||
signal io_addr : unsigned(15 downto 0);
|
||||
signal io_dout : unsigned(15 downto 0);
|
||||
signal data_dout : unsigned(15 downto 0);
|
||||
signal inst_addr : unsigned(12 downto 0);
|
||||
signal data_addr : unsigned(12 downto 0);
|
||||
signal data_we : std_logic;
|
||||
signal data_en : std_logic;
|
||||
|
||||
type rom_t is array (integer range <>) of unsigned(15 downto 0);
|
||||
|
||||
signal rom : rom_t(0 to 15) :=
|
||||
(
|
||||
X"8123", -- 0000
|
||||
X"0002", -- 0001
|
||||
X"0005", -- 0002
|
||||
X"8456", -- 0003
|
||||
X"4008", -- 0004
|
||||
X"0003", -- 0005
|
||||
X"0000", -- 0006
|
||||
X"0000", -- 0007
|
||||
X"8456", -- 0008
|
||||
X"8451", -- 0009
|
||||
X"7000", -- 000A
|
||||
X"0000", -- 000B
|
||||
X"0000", -- 000C
|
||||
X"0000", -- 000D
|
||||
X"0000", -- 000E
|
||||
X"0000" -- 000F
|
||||
);
|
||||
|
||||
BEGIN
|
||||
|
||||
-- Instruction rom
|
||||
process(sys_clk_i)
|
||||
begin
|
||||
if rising_edge(sys_clk_i) then
|
||||
inst_din <= rom(to_integer(inst_addr(3 downto 0)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
uut: entity work.j1
|
||||
PORT MAP
|
||||
(
|
||||
sys_clk_i => sys_clk_i,
|
||||
sys_rst_i => sys_rst_i,
|
||||
io_din => io_din,
|
||||
io_rd => io_rd,
|
||||
io_wr => io_wr,
|
||||
io_addr => io_addr,
|
||||
inst_din => inst_din,
|
||||
inst_addr => inst_addr,
|
||||
data_addr => data_addr,
|
||||
data_we => data_we,
|
||||
data_en => data_en,
|
||||
data_din => data_din,
|
||||
data_dout => data_dout
|
||||
);
|
||||
|
||||
inst_ram: entity work.ram_2c_2r_2w
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 13,
|
||||
data_width => 16
|
||||
)
|
||||
PORT MAP(
|
||||
clka => sys_clk_i,
|
||||
clkb => sys_clk_i,
|
||||
en_a => '1',
|
||||
en_b => data_en,
|
||||
we_a => '0',
|
||||
we_b => data_we,
|
||||
addr_a => (others => '0'), --inst_addr
|
||||
addr_b => data_addr,
|
||||
din_a => (others => '0'),
|
||||
din_b => data_dout,
|
||||
dout_a => open, -- inst_din
|
||||
dout_b => data_din
|
||||
);
|
||||
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
sys_clk_i <= not sys_clk_i;
|
||||
end process;
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
begin
|
||||
|
||||
wait for 3*CLK_PERIOD;
|
||||
sys_rst_i <= '0';
|
||||
wait for 2*CLK_PERIOD;
|
||||
|
||||
|
||||
wait for 1000*CLK_PERIOD;
|
||||
|
||||
assert false report "Test finished" severity error;
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
Reference in New Issue
Block a user