📄 apex20ke_mf.vhd
字号:
--
-- Copyright (C) 1988-1999 Altera Corporation
-- Any megafunction design, and related net list (encrypted or decrypted),
-- support information, device programming or simulation file, and any other
-- associated documentation or information provided by Altera or a partner
-- under Altera's Megafunction Partnership Program may be used only to
-- program PLD devices (but not masked PLD devices) from Altera. Any other
-- use of such megafunction design, net list, support information, device
-- programming or simulation file, or any other related documentation or
-- information is prohibited for any other purpose, including, but not
-- limited to modification, reverse engineering, de-compiling, or use with
-- any other silicon devices, unless such use is explicitly licensed under
-- a separate agreement with Altera or a megafunction partner. Title to
-- the intellectual property, including patents, copyrights, trademarks,
-- trade secrets, or maskworks, embodied in any such megafunction design,
-- net list, support information, device programming or simulation file, or
-- any other related documentation or information provided by Altera or a
-- megafunction partner, remains with Altera, the megafunction partner, or
-- their respective licensors. No other licenses, including any licenses
-- needed under any third party's intellectual property, are provided herein.
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Version 1.00 Date: 11/15/99
-- 09/20/99:
-- changed ALTPLL name to ALTCLKLOCK
-- changed mult_factor_clock0 to clock0_boost
-- changed mult_factor_clock1 to clock1_boost
-- changed divide_factor_clock0 to clock0_divide
-- changed divide_factor_clock1 to clock1_divide
-- added lvds_rx and lvds_tx megafuntions
--
-- 09/28/99:
-- lvds receiver:
-- changed input_frequency to inclock_frequency
-- changed rx_clkin to rx_inclock
-- changed rx_outclk to rx_outclock
-- corrected the x7 loop index problem
-- lvds transmitter:
-- changed input_frequency to inclock_frequency
-- changed tx_clkin to tx_inclock
-- changed tx_outclk to tx_outclock
-- changed synch_clock_in to sync_inclock
--
-- 10/05/99:
-- Changed inclock_frequency to inclock_period for ALTCLKLOCK, ALTLVDS_RX,
-- and ALTLVDS_TX
--
-- 10/19/99:
-- SPR65264: Corrected CAM initialization from *.hex; i.e. fix to
-- function hex_to_stdlogicarray (s: string).
--
-- 10/22/99:
-- SPR65544: Corrected SINGLE mode operation when outputreg is clocked
-- on either "INCLOCK" or "OUTCLOCK".
--
-- 10/27/99:
-- SPR65010: Fixed lvds reciever and transmitter number of cycles to output.
-- Converted integer and positive types to natural to work with
-- Quartus Wizzard.
-- Changed altclklock outclock_phase_shift type from real to natural
-- which defaults to ps.
-- 11/15/99: Fixed the lvds deskew according to the new spec.
-- 11/15/99: Made altclklock locked output sensetive to clock variations
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use std.textio.all;
entity altcam is
generic
( width: natural ;
widthad: natural ;
numwords: natural := 0;
lpm_file: string := "UNUSED";
lpm_filex: string := "UNUSED";
match_mode: string := "MULTIPLE";
output_reg: string := "UNREGISTERED";
output_aclr: string := "OFF";
pattern_reg: string := "INCLOCK";
pattern_aclr: string := "ON";
wraddress_aclr: string := "ON";
wrx_reg: string := "INCLOCK";
wrx_aclr: string := "ON";
wrcontrol_aclr: string := "OFF" );
port
( pattern: in std_logic_vector(width-1 downto 0);
wrx: in std_logic_vector(width-1 downto 0) := (others => '0');
wrxused: in std_logic := '0';
wrdelete: in std_logic := '0';
wraddress: in std_logic_vector(widthad-1 downto 0);
wren: in std_logic;
inclock: in std_logic;
inclocken: in std_logic := '1';
inaclr: in std_logic := '0';
mstart: in std_logic := '0';
mnext: in std_logic := '0';
outclock: in std_logic := '0';
outclocken: in std_logic := '1';
outaclr: in std_logic := '0';
maddress: out std_logic_vector(widthad-1 downto 0);
mbits: out std_logic_vector(numwords-1 downto 0);
mfound: out std_logic;
mcount: out std_logic_vector(widthad-1 downto 0);
rdbusy: out std_logic;
wrbusy: out std_logic );
type lpm_memory is array
((2**widthad)-1 downto 0) of std_logic_vector(width-1 downto 0);
function int_to_str( value : integer ) return string is
variable ivalue,index : integer;
variable digit : integer;
variable line_no: string(8 downto 1) := " ";
begin
ivalue := value;
index := 1;
while (ivalue > 0 ) loop
digit := ivalue MOD 10;
ivalue := ivalue/10;
case digit is
when 0 =>
line_no(index) := '0';
when 1 =>
line_no(index) := '1';
when 2 =>
line_no(index) := '2';
when 3 =>
line_no(index) := '3';
when 4 =>
line_no(index) := '4';
when 5 =>
line_no(index) := '5';
when 6 =>
line_no(index) := '6';
when 7 =>
line_no(index) := '7';
when 8 =>
line_no(index) := '8';
when 9 =>
line_no(index) := '9';
when others =>
ASSERT FALSE
REPORT "Illegal number!"
SEVERITY ERROR;
end case;
index := index + 1;
end loop;
return line_no;
end;
function hex_str_to_int( str : string ) return integer is
variable len : integer := str'length;
variable ivalue : integer := 0;
variable digit : integer;
begin
for i in len downto 1 loop
case str(i) is
when '0' =>
digit := 0;
when '1' =>
digit := 1;
when '2' =>
digit := 2;
when '3' =>
digit := 3;
when '4' =>
digit := 4;
when '5' =>
digit := 5;
when '6' =>
digit := 6;
when '7' =>
digit := 7;
when '8' =>
digit := 8;
when '9' =>
digit := 9;
when 'A' =>
digit := 10;
when 'a' =>
digit := 10;
when 'B' =>
digit := 11;
when 'b' =>
digit := 11;
when 'C' =>
digit := 12;
when 'c' =>
digit := 12;
when 'D' =>
digit := 13;
when 'd' =>
digit := 13;
when 'E' =>
digit := 14;
when 'e' =>
digit := 14;
when 'F' =>
digit := 15;
when 'f' =>
digit := 15;
when others =>
ASSERT FALSE
REPORT "Illegal character "& str(i) & "in Intel Hex File! "
SEVERITY ERROR;
end case;
ivalue := ivalue * 16 + digit;
end loop;
return ivalue;
end;
procedure Shrink_line(L : inout LINE; pos : in integer)
is
subtype nstring is string(1 to pos);
variable stmp : nstring;
begin
if pos >= 1 then
read(l,stmp);
end if;
end;
function hex_to_stdlogicarray (s: string) return lpm_memory is
variable mem_data : lpm_memory;
variable mem_data_tmp : integer := 0;
variable i,j,k,lineno: integer := 0;
variable buf: line ;
variable booval: boolean ;
FILE mem_data_file: TEXT IS IN s;
variable base, byte, rec_type, datain, checksum: string(2 downto 1);
variable startadd: string(4 downto 1);
variable ibase: integer := 0;
variable ibyte: integer := 0;
variable istartadd: integer := 0;
variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
begin
WHILE NOT ENDFILE(mem_data_file) loop
booval := true;
READLINE(mem_data_file, buf);
lineno := lineno + 1;
check_sum_vec := (OTHERS => '0');
if (buf(buf'LOW) = ':') then -- check for start of record char ':'
i := 1;
shrink_line(buf, i);
READ(L=>buf, VALUE=>byte, good=>booval); -- read length of record (2 hex chars)
if not (booval) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
SEVERITY ERROR;
end if;
ibyte := hex_str_to_int(byte);
check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
READ(L=>buf, VALUE=>startadd, good=>booval); -- read start/load address (4 hex chars)
if not (booval) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
SEVERITY ERROR;
end if;
istartadd := hex_str_to_int(startadd);
byte(2) := startadd(4);
byte(1) := startadd(3);
check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(byte), 8));
byte(2) := startadd(2);
byte(1) := startadd(1);
check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(byte), 8));
READ(L=>buf, VALUE=>rec_type, good=>booval); -- read record type (2 hex chars)
if not (booval) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
SEVERITY ERROR;
end if;
check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
else
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
SEVERITY ERROR;
end if;
case rec_type is
when "00"=> -- Data record
i := 0;
k := width/8;
if ( (width MOD 8) /= 0 ) then
k := k + 1;
end if;
-- k = no. of bytes per CAM entry.
while( i < ibyte ) loop
mem_data_tmp := 0;
for j in 1 to k loop
READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
if not (booval) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
SEVERITY ERROR;
end if;
check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
mem_data_tmp := mem_data_tmp * 256 + hex_str_to_int(datain);
end loop;
i := i + k;
mem_data(ibase + istartadd) := CONV_STD_LOGIC_VECTOR(mem_data_tmp, width);
istartadd := istartadd + 1;
end loop;
when "01"=>
exit;
when "02"=>
ibase := 0;
if (ibyte /= 2) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
SEVERITY ERROR;
end if;
for i in 0 to (ibyte-1) loop
READ(L=>buf, VALUE=>base,good=>booval);
if not (booval) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
SEVERITY ERROR;
end if;
ibase := ibase * 256 + hex_str_to_int(base);
check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
end loop;
ibase := ibase * 16; -- because std load addr is 2 bytes.
when OTHERS =>
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
SEVERITY ERROR;
end case;
READ(L=>buf, VALUE=>checksum,good=>booval);
if not (booval) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
SEVERITY ERROR;
end if;
check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
if (check_sum_vec /= check_sum_vec_tmp) then
ASSERT FALSE
REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
SEVERITY ERROR;
end if;
end loop;
return mem_data;
end;
end altcam;
architecture behave of altcam is
signal pattern_rgd: std_logic_vector(width-1 downto 0); -- registered input
signal pattern_int: std_logic_vector(width-1 downto 0); -- internal input
signal wrx_rgd: std_logic_vector(width-1 downto 0); -- registered input
signal wrxused_rgd : std_logic;
signal wrxused_int : std_logic;
signal wrx_int: std_logic_vector(width-1 downto 0); -- internal input
signal wraddress_rgd: std_logic_vector(widthad-1 downto 0); -- registered input
signal wren_rgd: std_logic; -- registered input
signal maddress_rgd: std_logic_vector(widthad-1 downto 0); --registered output
signal maddress_int: std_logic_vector(widthad-1 downto 0) := (others => 'U'); -- internal output
signal mbits_rgd: std_logic_vector(numwords-1 downto 0); -- registered output
signal mbits_int: std_logic_vector(numwords-1 downto 0) := (others => '0'); -- internal output
signal mfound_rgd: std_logic; -- registered output
signal matchfound_clk1: std_logic; -- registered output
signal mfound_int: std_logic := '0'; -- internal output
signal mcount_rgd: std_logic_vector(widthad-1 downto 0); -- registered output
signal mcount_int: std_logic_vector(widthad-1 downto 0) := (others => '0'); -- internal output
signal cam_array: lpm_memory;
signal x_array: lpm_memory;
signal mstart_last_value : std_logic;
signal first_read_clock : boolean := false;
signal second_read_clock : boolean := false;
signal next_read_clock : boolean := false;
signal write_clock : std_logic;
signal get_next_match : std_logic := '0';
signal wrbusy_int : std_logic := '0';
signal write_start : std_logic;
signal rdbusy_int : std_logic := '0';
signal cam_init: integer := 1;
signal write_start_rgd: std_logic := '0';
signal write_start_1: std_logic := '0';
signal mstart_rgd1: std_logic := '0';
signal mstart_rgd2: std_logic := '0';
signal print: integer := 1;
signal write_incomplete: std_logic := '0';
signal rdbusy_delayed : std_logic;
signal wrdelete_delayed : std_logic;
signal write0: boolean := true;
signal write1: boolean := false;
signal writex: boolean := false;
signal write0_done: boolean := false;
signal write1_done: boolean := false;
signal writex_done: boolean := false;
signal outclock_int: std_logic; -- internal outclock
signal outaclr_int: std_logic; -- internal outaclr
begin
msg: process (wraddress_rgd, wrdelete, wrdelete_delayed, wren_rgd,
wrxused_int, pattern_int, mstart_rgd1)
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -