📄 opb_epp.vhd
字号:
-- opb_epp module
-- this module can transfer data from address 0 to FB FFFF to the OPB bus
-- connects OPB bus to PC by Parallel Port (EPP mode) and epp.exe program
-- Generates System Reset OPB_Rst (Address: 0xFF FFF0 - FF FFFF) (write 1 to set, write 0 to clear)
-- Allows to use internal Logic Analyser to analyse OPB bus activity, LA Base Address= FF C000
-- by Erenst Jamro
--//////////////////////////////////////////////////////////////////////
--//// Copyright (C) 2003 Authors ////
--//// ////
--//// This source file may be used and distributed without ////
--/// restriction provided that this copyright statement is not ////
--//// removed from the file and that any derivative work contains ////
--//// the original copyright notice and the associated disclaimer. ////
--//// ////
--//// This source file is free software; you can redistribute it ////
--//// and/or modify it under the terms of the GNU Lesser General ////
--//// Public License as published by the Free Software Foundation; ////
--//// either version 2.1 of the License, or (at your option) any ////
--//// later version. ////
--//// ////
--//// This source 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 Lesser General Public License for more ////
--//// details. ////
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library UNISIM;
use unisim.all; -- for global set reset signal
entity opb_epp is
generic (c_opb_dwidth: integer:= 32; -- OPB data bus width
c_opb_awidth: integer:= 32; -- OPB address bus width
c_real_dwidth: integer:= 8; -- real OPB data width (the rest lSBs are always 0s)
c_use_seqAddr: integer:= 1; -- use seqAddr for OPB bus transfer
c_la_mwidth: integer:= 9; -- internal memory address width (number of samples= 2**c_la_mwidth
-- if <4 do not instantiate logic analyser at all
c_la_run_length_coding: integer:= 0; -- include run length codding logic
c_la_dwidth: integer:= 8; -- internal logic analyser data width= 8, 16 or 32
c_la_dtype: integer:= 0; -- 0- use internal data, 1- use external data, 2- OPB_ABus, 3- OPB_DBus
c_la_twidth: integer:= 8; -- trigger width
c_la_ttype: integer:= 0; -- trigger data type= 0- internal, 1- external, 2- OPB_ABus, 3- OPB_DBus 4- same as la_dbus
c_la_ce_dwidth: integer:= 8; -- width of the data clock enable
c_la_ce_dtype: integer:= 3; -- data clock enable= 0- standard connecttion, 1 - external, 2- same as data, 3- same as trigger
c_la_ce_ttype: integer:= 0); -- trigger clock enable= 0- always '1', 1- external,
-- 2- '1' when OPB_select='1'; 3 - '1' when OPB_xferAck='1', 4 - '1' when OPB_errAck='1' or OPB_xferAck or OPB_retry='1', 5- OPB_rst
port (OPB_clk: in STD_LOGIC;
OPB_rst: in STD_LOGIC;
-- OPB interface
M_ABus : out STD_LOGIC_VECTOR(0 TO c_opb_awidth-1); -- is already gated by M_Select
M_BE : out STD_LOGIC_VECTOR(0 TO c_opb_dwidth/8 -1);
M_RNW : out STD_LOGIC;
M_select : out STD_LOGIC;
M_seqAddr : out STD_LOGIC;
M_busLock : out STD_LOGIC;
M_DBus : out STD_LOGIC_VECTOR(0 TO c_opb_dwidth-1);
M_request : out STD_LOGIC;
OPB_MGrant: in STD_LOGIC;
OPB_pendReq: in STD_LOGIC;
OPB_DBus : in STD_LOGIC_VECTOR(0 TO c_opb_dwidth-1);
OPB_errAck : in STD_LOGIC;
OPB_retry : in STD_LOGIC;
OPB_timeout: in STD_LOGIC;
OPB_xferAck : in STD_LOGIC;
OPB_RNW: in STD_LOGIC;
OPB_ABus: in std_logic_vector(0 to c_opb_awidth-1);
OPB_select: in std_logic; -- used only by LA
OPB_seqAddr: in STD_LOGIC; -- used only by LA
OPB_busLock: in STD_LOGIC; -- used only by LA
OPB_toutSup: in STD_LOGIC; -- used only by LA
-- generate OPB_RST signal
SYS_rst: out std_logic;
-- logic analyser data (triger is the same assert data
la_DBus: in std_logic_vector(0 to c_la_dwidth-1); -- LA data bus
la_TBus: in std_logic_vector(0 to c_la_twidth-1); -- LA triger bus
la_ceDBus: in std_logic_vector(0 to c_la_ce_dwidth-1); -- LA clock enable data bus
la_ceTBus: in std_logic; -- clock enable for la_TBus
-- external (PIN) signals connected to CPLD and Parallel Port (FPGA is a slave device to CPLD!)
pp_dck: in STD_LOGIC; -- parallel port (PP) data clock
pp_dwr: in STD_LOGIC; -- PP data write
pp_drd: out std_logic -- PP data read
);
end opb_epp;
architecture opb_epp_arch of opb_epp is
component epp
port (clk_I: in STD_LOGIC;
arst: in STD_LOGIC; -- asynchronous global reset
-- WISHBONE interface
adr_O: buffer std_logic_vector(31 downto 0);
we_O, cyc_O, stb_O: buffer std_logic;
ack_I: in std_logic;
dat_O: out std_logic_vector(7 downto 0);
dat_I: in std_logic_vector(7 downto 0);
cti_O: out std_logic_vector(2 downto 0); -- sequencial addressing
buf_valid: in std_logic; -- write data in the external buffer are alid so do not change the address (only +1 is allowed)
-- external (PIN) signals connected to CPLD and Parallel Port (FPGA is a slave device to CPLD!)
pp_dck: in STD_LOGIC; -- Parallel Port Clock
pp_dwr: in STD_LOGIC; -- PP data write
pp_drd: out std_logic -- PP data read
);
end component;
component ROC -- reset on Configuration
port (O : out std_logic);
end component;
component epp_dwidth -- convert 8-bit to 16 or 32 bit data
generic(dwidth: integer:= 32;
use_seqAddr: integer:= 1); -- assume that the read or write is sequancial
port (clk, arst: in std_logic;
-- common logic
seqAddr: in std_logic; -- the next read /writes will be sequencial- use always seqAddr when transfering data unless use_seqAddr<=0
rnw: in std_logic; -- read not write
buf_valid: out std_logic; -- valid data write buffer - do not change the address and rnw
-- 8-bit data interface
adr8: in std_logic_vector(0 to 31);
stb8: in std_logic;
ack8: out std_logic;
din8: in std_logic_vector(0 to 7);
dout8: out std_logic_vector(0 to 7);
-- dwidth data interface
adr: out std_logic_vector(0 to 31);
stb: out std_logic;
ack: in std_logic;
be: out std_logic_vector(0 to dwidth/8-1);
din: in std_logic_vector(0 to dwidth-1);
dout: out std_logic_vector(0 to dwidth-1));
end component;
component opb_master
generic(opb_dwidth: integer:= 32; -- opb master data width
dwidth: integer:= 16; -- internal (real) data width the MSB of OPB_DBus='0'
opb_awidth: integer:= 32; -- opb address bus width
awidth: integer:= 16; -- internal address bus width
transfer_size: integer:= 4); -- max transfer size when bus is locked (valid only when seqAddr>0)
port(clk, arst: std_logic; --clock and global asynchronous reset
-- OPB Master interface
M_ABus : out STD_LOGIC_VECTOR(0 TO opb_awidth-1); -- is already gated by M_Select
M_BE : out STD_LOGIC_VECTOR(0 TO opb_dwidth/8 -1);
M_RNW : out STD_LOGIC;
M_select : out STD_LOGIC;
M_seqAddr : out STD_LOGIC;
M_busLock : out STD_LOGIC;
M_DBus : out STD_LOGIC_VECTOR(0 TO opb_dwidth-1);
M_request : out STD_LOGIC;
OPB_MGrant: in STD_LOGIC;
OPB_pendReq: in STD_LOGIC;
OPB_DBus : in STD_LOGIC_VECTOR(0 TO opb_dwidth-1);
OPB_errAck : in STD_LOGIC;
OPB_retry : in STD_LOGIC;
OPB_timeout: in STD_LOGIC;
OPB_xferAck : in STD_LOGIC;
-- internal simplified bus
di: in std_logic_vector(0 to dwidth-1); -- data input
do: out std_logic_vector(0 to dwidth-1); -- data output
be: in std_logic_vector(0 to dwidth/8 -1); -- byte enable
a: in std_logic_vector(0 to awidth-1); -- address bus
msb_adr: in std_logic_vector(0 to opb_awidth-1):= (others=>'0');
rnw: in std_logic; -- read not write
sel: in std_logic; -- OPB select signal
seqAddr: in std_logic;
ack: out std_logic);
end component;
component log_anal
generic(data_width: integer:= 16; -- width of the data that are analysed (must be power of 2)
mem_adr_width: integer:= 9; -- internal memory address width
adr_width: integer:= 11; -- adr_I address width
trig_width: integer:= 8; -- width of the triger logic
ce_dwidth: integer:= 1; -- data clock enable trigger-like logic width
ced_type: integer:= 1; -- 0 - data clock enable logic is desabled, 1- enable data clock enable logic
two_clocks: integer:= 0; -- two seperate clocks for control interface and logic analyser
use_run_length_coding: integer:= 0);
-- the following rules must!!! be satysfied for generic:
-- data_width= 8, 16, 32, 64
-- adr_width= mem_adr_width + 1 + log2(data_width/8); 4<=mem_adr_width<=16
-- mem_adr_width<=16
-- trig_width<= 64
-- two_clocks= 0 (only wb_clk_I clock is used) 1- f_clk= k*f_wb_clk_I, 2- two asynchronous clocks
-- mem_adr_width optimal selection for 4kb BRAM (Virtex):
-- mem_adr_width<= 9 then number of BRAM block used= data_width/8
port (arst: in std_logic; -- global asynchronous set reset signal (mainly for simulation purposes)
-- interface for logic analyser
clk: in std_logic; -- seperate clock for logic analyzer (the same as wb_clk_I when two_clocks= 0)
data: in std_logic_vector(data_width-1 downto 0); -- data that are analysied
ce_data: in std_logic_vector(ce_dwidth-1 downto 0); -- clock enable -- should be used if data are recorded e.g. every second la_clk
trig: in std_logic_vector(trig_width-1 downto 0); -- triger bus (can be different that data bus
ce_trig: in std_logic; -- clock enable for triger bus
-- control WISHBOBE slave interface - interface for setting logic analyser options and transfering analysed data to computer
wb_clk_I: in STD_LOGIC; -- clock (common for every logic every logic analyser signals) - common for loagic analyser and WISHBONE control interface
wb_adr_I: in std_logic_vector(adr_width-1 downto 0); -- address bus (one bit wider than mem_adr_width)
wb_dat_I: in std_logic_vector(7 downto 0);
wb_dat_O: out std_logic_vector(7 downto 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -