Add fjmem example for Spartan-6 devices

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1853 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Mike Frysinger 14 years ago
parent 183d46a331
commit a0269f602d

@ -28,6 +28,9 @@
doc/Makefile.am, doc/README.pld, src/global/log-error.c, configure.ac:
New Programmable Logic Devices (PLD) subsystem by Michael Walle.
* extra/fjmem/fjmem_config_pack_spartan6-p.vhd, extra/fjmem/fjmem_spartan6.vhd:
Add fjmem example for Spartan-6 devices.
2010-08-30 Mike Frysinger <vapier@gentoo.org>
* configure.ac: Clean up libusb detection to prefer 1.0 over 0.1, and accept

@ -0,0 +1,82 @@
-------------------------------------------------------------------------------
--
-- $Id$
--
-- 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 2
-- 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, write to the Free Software
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-- 02111-1307, USA.
--
-- Written by Michael Walle <michael@walle.cc>, 2010.
-- Based on fjmem_config_pack_spartan3-p.vhd by Arnim Laeuger.
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package fjmem_config_pack is
-----------------------------------------------------------------------------
-- Specify the active levels of trst_i, shift_i and res_i
--
constant trst_act_level_c : std_logic := '1';
constant shift_act_level_c : std_logic := '1';
constant res_act_level_c : std_logic := '1';
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Adapt the number of used blocks and the number of bits that are
-- required for the block field (2 ** num_block_field_c >= num_blocks_c)
--
-- number of used blocks
constant num_blocks_c : natural := 2;
-- number of bits for block field
constant num_block_field_c : natural := 1;
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Don't change the array type
--
type block_desc_t is
record
addr_width : natural;
data_width : natural;
end record;
type block_array_t is array (natural range 0 to num_blocks_c-1) of block_desc_t;
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Fill in the array for all your used blocks
--
constant blocks_c : block_array_t :=
((addr_width => 24, -- block #0, FLASH
data_width => 16),
(addr_width => 8, -- block #1, dummy
data_width => 8)
);
--
-- And specify the maximum address and data width
--
constant max_addr_width_c : natural := 24;
constant max_data_width_c : natural := 16;
--
-----------------------------------------------------------------------------
end;

@ -0,0 +1,320 @@
-------------------------------------------------------------------------------
--
-- $Id$
--
-- 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 2
-- 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, write to the Free Software
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-- 02111-1307, USA.
--
-- Written by Michael Walle <michael@walle.cc>, 2010.
-- Based on fjmem_spartan3.vhd by Arnim Laeuger.
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity fjmem_spartan6 is
port (
-- Clock oscillator
osc1 : in std_logic;
-- Flash Memory
fl_a : out std_logic_vector(23 downto 0);
fl_d : inout std_logic_vector(15 downto 0);
fl_ce_n : out std_logic;
fl_oe_n : out std_logic;
fl_we_n : out std_logic;
fl_rp_n : out std_logic;
fl_sts : in std_logic;
led : out std_logic_vector(1 downto 0)
);
end fjmem_spartan6;
library ieee;
use ieee.numeric_std.all;
use work.fjmem_config_pack.all;
architecture struct of fjmem_spartan6 is
component fjmem_core
port (
clkdr_i : in std_logic;
trst_i : in std_logic;
shift_i : in std_logic;
update_i : in std_logic;
tdi_i : in std_logic;
tdo_o : out std_logic;
clk_i : in std_logic;
res_i : in std_logic;
strobe_o : out std_logic;
read_o : out std_logic;
write_o : out std_logic;
ack_i : in std_logic;
cs_o : out std_logic_vector(num_blocks_c-1 downto 0);
addr_o : out std_logic_vector(max_addr_width_c-1 downto 0);
din_i : in std_logic_vector(max_data_width_c-1 downto 0);
dout_o : out std_logic_vector(max_data_width_c-1 downto 0)
);
end component;
component BSCAN_SPARTAN6
port (
CAPTURE : out std_ulogic := 'H';
DRCK : out std_ulogic := 'L';
RESET : out std_ulogic := 'L';
RUNTEST : out std_ulogic := 'L';
SEL : out std_ulogic := 'L';
SHIFT : out std_ulogic := 'L';
TCK : out std_ulogic := 'L';
TDI : out std_ulogic := 'L';
TMS : out std_ulogic := 'L';
UPDATE : out std_ulogic := 'L';
TDO : in std_ulogic := 'X'
);
end component;
signal tdi_s,
tdo_s : std_logic;
signal clkdr_s,
trst_s,
shift_s,
update_s : std_logic;
signal addr_s : std_logic_vector(max_addr_width_c-1 downto 0);
signal din_s,
dout_s : std_logic_vector(max_data_width_c-1 downto 0);
signal res_s : std_logic;
signal read_s,
write_s,
strobe_s : std_logic;
signal cs_s : std_logic_vector(1 downto 0);
signal ack_q : std_logic;
type state_t is (IDLE,
READ_WAIT,
WRITE_DRIVE,
WRITE_WAIT,
WRITE_FINISH);
signal state_q : state_t;
signal cnt_q : unsigned(2 downto 0);
signal fl_ce_n_q,
fl_oe_n_q,
fl_we_n_q,
fl_d_en_q : std_logic;
begin
res_s <= '0';
bscan_spartan6_b : BSCAN_SPARTAN6
port map (
CAPTURE => open,
DRCK => clkdr_s,
RESET => open, --trst_s,
RUNTEST => open,
SEL => open,
SHIFT => shift_s,
TCK => open,
TDI => tdi_s,
TMS => open,
UPDATE => update_s,
TDO => tdo_s
);
trst_s <= '0';
fjmem_core_b : fjmem_core
port map (
clkdr_i => clkdr_s,
trst_i => trst_s,
shift_i => shift_s,
update_i => update_s,
tdi_i => tdi_s,
tdo_o => tdo_s,
clk_i => osc1,
res_i => res_s,
strobe_o => strobe_s,
read_o => read_s,
write_o => write_s,
ack_i => ack_q,
cs_o => cs_s,
addr_o => addr_s,
din_i => din_s,
dout_o => dout_s
);
-----------------------------------------------------------------------------
-- Process mem_ctrl
--
-- Purpose:
-- Handles access to external memory.
--
mem_ctrl: process (res_s, osc1)
begin
if res_s = '1' then
-- Flash
fl_ce_n_q <= '1';
fl_oe_n_q <= '1';
fl_we_n_q <= '1';
fl_d_en_q <= '0';
ack_q <= '0';
state_q <= IDLE;
cnt_q <= (others => '0');
elsif rising_edge(osc1) then
case state_q is
when IDLE =>
if strobe_s = '1' then
if write_s = '1' then
state_q <= WRITE_DRIVE;
else
state_q <= READ_WAIT;
ack_q <= '1';
end if;
case cs_s is
-- Flash
when "01" =>
fl_ce_n_q <= '0';
if read_s = '1' then
fl_oe_n_q <= '0';
-- start counter on read
cnt_q <= (others => '1');
end if;
if write_s = '1' then
fl_d_en_q <= '1';
end if;
-- unimlemented / invalid
when others =>
null;
end case;
end if;
when READ_WAIT =>
if cnt_q = 0 then
state_q <= IDLE;
ack_q <= '0';
-- disable all memories
fl_ce_n_q <= '1';
fl_oe_n_q <= '1';
end if;
when WRITE_DRIVE =>
state_q <= WRITE_WAIT;
-- output drivers are active during this state
-- thus we can activate the write impulse at the end
case cs_s is
when "01" =>
fl_we_n_q <= '0';
-- start counter
cnt_q <= (others => '1');
when others =>
null;
end case;
when WRITE_WAIT =>
if cnt_q = 0 then
state_q <= WRITE_FINISH;
ack_q <= '0';
-- disable write signals
fl_we_n_q <= '1';
end if;
when WRITE_FINISH =>
state_q <= IDLE;
-- disable output enables
fl_d_en_q <= '0';
-- disable all memories
fl_ce_n_q <= '1';
fl_oe_n_q <= '1';
when others =>
state_q <= IDLE;
end case;
if cnt_q /= 0 then
cnt_q <= cnt_q - 1;
end if;
end if;
end process mem_ctrl;
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Process read_mux
--
-- Purpose:
-- Read multiplexer from memory to jop_core.
--
read_mux: process (cs_s, fl_d)
variable din_v : std_logic_vector(din_s'range);
begin
din_v := (others => '0');
if cs_s(0) = '1' then
din_v := din_v or fl_d;
end if;
din_s <= din_v;
end process read_mux;
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Pin defaults
-----------------------------------------------------------------------------
-- Flash Memory -------------------------------------------------------------
fl_addr: process (addr_s)
begin
-- fl_a <= (others => '0');
fl_a(23 downto 0) <= addr_s;
end process fl_addr;
fl_d <= dout_s
when fl_d_en_q = '1' else
(others => 'Z');
fl_ce_n <= fl_ce_n_q;
fl_oe_n <= fl_oe_n_q;
fl_we_n <= fl_we_n_q;
fl_rp_n <= '1';
-- LEDs
led(0) <= fl_we_n_q;
led(1) <= fl_oe_n_q;
end struct;
Loading…
Cancel
Save