📄 logan.vhd
字号:
------------------------------------------------------------------------------- Entity: logan-- File: logan.vhd-- Author: Kristoffer Carlsson-- Description: On-chip logic analyzer IP core-----------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;use grlib.tech.all;library gaisler;use gaisler.devices.all;use gaisler.memory.all;entity logan is generic ( dbits : integer range 0 to 256 := 32; -- Number of traced signals depth : integer range 256 to 16384 := 1024; -- Depth of trace buffer trigl : integer range 1 to 63 := 1; -- Number of trigger levels usereg : integer range 0 to 1 := 1; -- Use input register usequal : integer range 0 to 1 := 0; -- Use qualifer bit pindex : integer := 0; paddr : integer := 0; pmask : integer := 16#F00#; memtech : integer := DEFMEMTECH); port ( rstn : in std_logic; -- Synchronous reset clk : in std_logic; -- System clock tclk : in std_logic; -- Trace clock apbi : in apb_slv_in_type; -- APB in record apbo : out apb_slv_out_type; -- APB out record signals : in std_logic_vector(dbits - 1 downto 0)); -- Traced signalsend logan;architecture rtl of logan is constant REVISION : amba_version_type := 0; constant pconfig : apb_config_type := ( 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_LOGAN, 0, REVISION, 0), 1 => apb_iobar(paddr, pmask)); constant abits: integer := 8 + log2x(depth/256 - 1); constant az : std_logic_vector(abits-1 downto 0) := (others => '0'); constant dz : std_logic_vector(dbits-1 downto 0) := (others => '0'); type trig_cfg_type is record pattern : std_logic_vector(dbits-1 downto 0); -- Pattern to trig on mask : std_logic_vector(dbits-1 downto 0); -- trigger mask count : std_logic_vector(5 downto 0); -- match counter eq : std_ulogic; -- Trig on match or no match? end record; type trig_cfg_arr is array (0 to trigl-1) of trig_cfg_type; type reg_type is record armed : std_ulogic; trig_demet : std_ulogic; trigged : std_ulogic; fin_demet : std_ulogic; finished : std_ulogic; qualifier : std_logic_vector(7 downto 0); qual_val : std_ulogic; divcount : std_logic_vector(15 downto 0); counter : std_logic_vector(abits-1 downto 0); page : std_logic_vector(3 downto 0); trig_conf : trig_cfg_arr; end record; type trace_reg_type is record armed : std_ulogic; arm_demet : std_ulogic; trigged : std_ulogic; finished : std_ulogic; sample : std_ulogic; divcounter : std_logic_vector(15 downto 0); match_count : std_logic_vector(5 downto 0); counter : std_logic_vector(abits-1 downto 0); curr_tl : integer range 0 to trigl-1; w_addr : std_logic_vector(abits-1 downto 0); end record; signal r_addr : std_logic_vector(13 downto 0); signal bufout : std_logic_vector(255 downto 0); signal r_en : std_ulogic; signal r, rin : reg_type; signal tr, trin : trace_reg_type; signal sigreg : std_logic_vector(dbits-1 downto 0); signal sigold : std_logic_vector(dbits-1 downto 0);begin bufout(255 downto dbits) <= (others => '0'); -- Combinatorial process for AMBA clock domain comb1: process(rstn, apbi, r, tr, bufout) variable v : reg_type; variable rdata : std_logic_vector(31 downto 0); variable tl : integer range 0 to trigl-1; variable pattern, mask : std_logic_vector(255 downto 0); begin v := r; rdata := (others => '0'); tl := 0; pattern := (others => '0'); mask := (others => '0'); -- Two stage synch v.trig_demet := tr.trigged; v.trigged := r.trig_demet; v.fin_demet := tr.finished; v.finished := r.fin_demet; if r.finished = '1' then v.armed := '0'; end if; r_en <= '0'; -- Read/Write -- if apbi.penable = '1' and apbi.psel(pindex) = '1' then -- Write if apbi.pwrite = '1' then -- Only conf area writeable if apbi.paddr(15) = '0' then -- pattern/mask if apbi.paddr(14 downto 13) = "11" then tl := conv_integer(apbi.paddr(11 downto 6)); pattern(dbits-1 downto 0) := v.trig_conf(tl).pattern; mask(dbits-1 downto 0) := v.trig_conf(tl).mask; case apbi.paddr(5 downto 2) is when "0000" => pattern(31 downto 0) := apbi.pwdata; when "0001" => pattern(63 downto 32) := apbi.pwdata; when "0010" => pattern(95 downto 64) := apbi.pwdata; when "0011" => pattern(127 downto 96) := apbi.pwdata; when "0100" => pattern(159 downto 128) := apbi.pwdata; when "0101" => pattern(191 downto 160) := apbi.pwdata; when "0110" => pattern(223 downto 192) := apbi.pwdata; when "0111" => pattern(255 downto 224) := apbi.pwdata; when "1000" => mask(31 downto 0) := apbi.pwdata; when "1001" => mask(63 downto 32) := apbi.pwdata; when "1010" => mask(95 downto 64) := apbi.pwdata; when "1011" => mask(127 downto 96) := apbi.pwdata; when "1100" => mask(159 downto 128) := apbi.pwdata; when "1101" => mask(191 downto 160) := apbi.pwdata; when "1110" => mask(223 downto 192) := apbi.pwdata; when "1111" => mask(255 downto 224) := apbi.pwdata; when others => null; end case; -- write back updated pattern/mask v.trig_conf(tl).pattern := pattern(dbits-1 downto 0); v.trig_conf(tl).mask := mask(dbits-1 downto 0); -- count/eq elsif apbi.paddr(14 downto 13) = "01" then tl := conv_integer(apbi.paddr(7 downto 2)); v.trig_conf(tl).count := apbi.pwdata(6 downto 1); v.trig_conf(tl).eq := apbi.pwdata(0); -- arm/reset elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00000" then v.armed := apbi.pwdata(0); -- Page reg elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00010" then v.page := apbi.pwdata(3 downto 0); -- Trigger counter elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00011" then v.counter := apbi.pwdata(abits-1 downto 0); -- div count elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00100" then v.divcount := apbi.pwdata(15 downto 0); -- qualifier bit elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00101" then v.qualifier := apbi.pwdata(7 downto 0); v.qual_val := apbi.pwdata(8); end if; end if; -- end write -- Read else -- Read config/status area if apbi.paddr(15) = '0' then -- pattern/mask if apbi.paddr(14 downto 13) = "11" then tl := conv_integer(apbi.paddr(11 downto 6)); pattern(dbits-1 downto 0) := v.trig_conf(tl).pattern; mask(dbits-1 downto 0) := v.trig_conf(tl).mask; case apbi.paddr(5 downto 2) is when "0000" => rdata := pattern(31 downto 0); when "0001" => rdata := pattern(63 downto 32); when "0010" => rdata := pattern(95 downto 64); when "0011" => rdata := pattern(127 downto 96); when "0100" => rdata := pattern(159 downto 128); when "0101" => rdata := pattern(191 downto 160); when "0110" => rdata := pattern(223 downto 192); when "0111" => rdata := pattern(255 downto 224); when "1000" => rdata := mask(31 downto 0); when "1001" => rdata := mask(63 downto 32); when "1010" => rdata := mask(95 downto 64); when "1011" => rdata := mask(127 downto 96);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -