You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
9267b24e1f
git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1084 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 |
17 years ago | |
---|---|---|
.. | ||
README | 17 years ago | |
fjmem_config_pack_cyclone-p.vhd | 17 years ago | |
fjmem_config_pack_spartan3-p.vhd | 17 years ago | |
fjmem_core.vhd | 17 years ago | |
fjmem_cyclone.vhd | 17 years ago | |
fjmem_pack-p.vhd | 17 years ago | |
fjmem_spartan3.vhd | 17 years ago | |
generic_ram_ena.vhd | 17 years ago |
README
FPGA JTAG Memory (fjmem) Design =============================== $Id$ Introduction ------------ This directory contains the VHDL design files that complement UrJTAG's fjmem bus driver. The fjmem system utilizes generic embedded JTAG components that are available in several FPGA families. These stubs connect to the fjmem_core design and act as the interface to the external JTAG chain. The fjmem_core design implements a data register that is hooked into the JTAG chain when a USER instruction is selected. UrJTAG communicates with fjmem_core by shifting command, address and data information through this register. This information is processed by fjmem_core and results in read or write operations on a generic memory interface. JTAG stubs ---------- Modern FPGA devices contain a JTAG component that allows user logic to connect to the external JTAG chain. Xilinx devices like the Spartan 3 call it BSCAN_SPARTAN3 while it's named cyclone_jtag in Altera's Cyclone devices. Apart from details, both components provide equivalent functionality: User logic can place a data shift register between TDI and TDO that is activated by special USER instructions. Xilinx BSCAN_SPARTAN3: * USER1, opcode 00010 * USER2, opcode 00011 Extensively documented in "Configuration and Readback of Spartan-II FPGAs Using Boundary Scan" (xapp188.pdf). Altera cyclone_jtag: * USER0, opcode 0000001100 * USER1, opcode 0000001110 Briefly mentioned in the "MAXII Device Handbook". Integration ----------- A short description of fjmem_core's ports: -- JTAG Interface clkdr_i - TCK clock trst_i - TAP reset shift_i - Shift enable update_i - Update clock tdi_i - TDI chain input tdo_o - TDO chain output -- Memory Interface clk_i - Clock res_i - Reset strobe_o - Strobe read_o - Read enable write_o - Write enable ack_i - Acknowledge cs_o - Chip select lines addr_o - Address vector din_i - Data input vector dout_o - Data output vector Whenever the fjmem_core receives a command from the fjmem bus driver, it issues the according signals on the memory interface. This interface is synchronous to clk_i. Active strobe_o announces a read or write operation. All other outputs are valid only when strobe_o is '1'. Access direction outputs read_o and write_o are mutually exclusive. cs_o is a one-hot vector and identifies the selected memory block. Two sample toplevel designs are provided for Cyclone and Spartan3 devices that demonstrate the attachment of asynchronous and synchronous (on-chip) memories. Configuration ------------- The specific configuration of fjmem_core is taken from fjmem_config_pack. The user has to set a number of constants that determine the behavior of the core design. -- Specify the active levels of trst_i, shift_i and res_i trst_act_level_c - TRST active level shift_act_level_c - Shift enable active level res_act_level_c - res_i active level A block is a consecutive memory range that has a common geometry, i.e. it represents a single memory component in the system. The number of block relates directly to the number of lines in the cs_o chip select vector. -- number of used blocks constant num_blocks_c : natural := 4; -- number of bits for block field constant num_block_field_c : natural := 2; Specify the geometry of each block: address and data vector width. The block (= memory range) is expected to use the full address vector width. constant blocks_c : block_array_t := ((addr_width => 18, -- block #0 data_width => 16), (addr_width => 18, -- block #1 data_width => 16), (addr_width => 19, -- block #2 data_width => 8), (addr_width => 8, -- block #3 data_width => 8) ); For completeness, it's required to set constants for the maximum address and data vector widths. constant max_addr_width_c : natural := 19; constant max_data_width_c : natural := 16;