diff --git a/lib/CPUs/J1/doc/j1.pdf b/lib/CPUs/J1/doc/j1.pdf new file mode 100644 index 0000000..188ac02 Binary files /dev/null and b/lib/CPUs/J1/doc/j1.pdf differ diff --git a/lib/CPUs/J1/sim/tb_j1.do b/lib/CPUs/J1/sim/tb_j1.do new file mode 100644 index 0000000..4fa1a55 --- /dev/null +++ b/lib/CPUs/J1/sim/tb_j1.do @@ -0,0 +1,15 @@ +## NOTE: Do not edit this file. +## +vlib work +vcom -explicit -93 "../src/core/ram_2c_2r_2w.vhd" +vcom -explicit -93 "../src/core/j1.vhd" +vcom -explicit -93 "../src/tb_j1.vhd" + +vmap work + +vsim -t 1ps -lib work tb_j1 +do {tb_j1.wave.do} +view wave +view structure +view signals +run 1us diff --git a/lib/CPUs/J1/sim/tb_j1.wave.do b/lib/CPUs/J1/sim/tb_j1.wave.do new file mode 100644 index 0000000..58c0f66 --- /dev/null +++ b/lib/CPUs/J1/sim/tb_j1.wave.do @@ -0,0 +1,58 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -format Logic /tb_j1/sys_clk_i +add wave -noupdate -format Logic /tb_j1/sys_rst_i +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/io_din +add wave -noupdate -format Logic /tb_j1/io_rd +add wave -noupdate -format Logic /tb_j1/io_wr +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/io_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/io_dout +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/inst_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/inst_din +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/data_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/data_din +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/data_dout +add wave -noupdate -format Logic /tb_j1/data_we +add wave -noupdate -format Logic /tb_j1/data_en +add wave -noupdate -divider {J1 internals} +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/insn +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/immediate +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/ramrd +add wave -noupdate -format Literal /tb_j1/uut/dsp +add wave -noupdate -format Literal /tb_j1/uut/dsp2 +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/st0 +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/st02 +add wave -noupdate -format Logic /tb_j1/uut/dstkw2 +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/pc +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/pc2 +add wave -noupdate -format Literal /tb_j1/uut/rsp +add wave -noupdate -format Literal /tb_j1/uut/rsp2 +add wave -noupdate -format Logic /tb_j1/uut/rstkw2 +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/rstkd2 +add wave -noupdate -format Logic /tb_j1/uut/ramwe2 +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/pc_plus_1 +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/dstack +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/rstack +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/st1 +add wave -noupdate -format Literal -radix hexadecimal /tb_j1/uut/rst0 +add wave -noupdate -format Literal /tb_j1/uut/st0sel +add wave -noupdate -format Logic /tb_j1/uut/is_alu +add wave -noupdate -format Logic /tb_j1/uut/is_lit +add wave -noupdate -format Literal /tb_j1/uut/dd +add wave -noupdate -format Literal /tb_j1/uut/rd +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {1600185 ps} 0} +configure wave -namecolwidth 150 +configure wave -valuecolwidth 100 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {0 ps} {1050 ns} diff --git a/lib/CPUs/J1/src/core/j1.v b/lib/CPUs/J1/src/core/j1.v new file mode 100644 index 0000000..861cb3c --- /dev/null +++ b/lib/CPUs/J1/src/core/j1.v @@ -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 diff --git a/lib/CPUs/J1/src/core/j1.vhd b/lib/CPUs/J1/src/core/j1.vhd new file mode 100644 index 0000000..d5c9f14 --- /dev/null +++ b/lib/CPUs/J1/src/core/j1.vhd @@ -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; diff --git a/lib/CPUs/J1/src/core/ram_2c_2r_2w.vhd b/lib/CPUs/J1/src/core/ram_2c_2r_2w.vhd new file mode 100644 index 0000000..23d8118 --- /dev/null +++ b/lib/CPUs/J1/src/core/ram_2c_2r_2w.vhd @@ -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 . +-- +-- 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; + diff --git a/lib/CPUs/J1/src/tb_j1.vhd b/lib/CPUs/J1/src/tb_j1.vhd new file mode 100644 index 0000000..8aa4c3c --- /dev/null +++ b/lib/CPUs/J1/src/tb_j1.vhd @@ -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 . +-- +-- 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; diff --git a/lib/ac97_ctrl/todo.txt b/lib/ac97_ctrl/todo.txt new file mode 100644 index 0000000..7abc706 --- /dev/null +++ b/lib/ac97_ctrl/todo.txt @@ -0,0 +1,2 @@ +2010-07-08 +- RX FIFO