##// END OF EJS Templates
Correction de la FSM qui regule les données entrant dans la FFT
Correction de la FSM qui regule les données entrant dans la FFT

File last commit:

r129:8459a437c1f1 alexis
r557:7faec0eb9fbb (MINI-LFR) WFP_MS-0-1-67 (LFR-EM) WFP_MS_1-1-67 JC
Show More
ahb2mig_sp605.vhd
508 lines | 16.5 KiB | text/x-vhdl | VhdlLexer
------------------------------------------------------------------------------
-- This file is a part of the GRLIB VHDL IP LIBRARY
-- Copyright (C) 2003 - 2008, Gaisler Research
-- Copyright (C) 2008 - 2012, Aeroflex Gaisler
--
-- 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
-------------------------------------------------------------------------------
-- Entity: ahb2mig_sp605
-- File: ahb2mig_sp605.vhd
-- Author: Jiri Gaisler - Aeroflex Gaisler AB
--
-- This is a AHB-2.0 interface for the Xilinx Spartan-6 MIG.
-- One bidir 32-bit port is used for the main AHB bus, while
-- a second read-only port can be enabled for a VGA frame buffer.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library grlib;
use grlib.amba.all;
use grlib.stdlib.all;
use grlib.devices.all;
entity ahb2mig_sp605 is
generic(
hindex : integer := 0;
haddr : integer := 0;
hmask : integer := 16#f00#;
pindex : integer := 0;
paddr : integer := 0;
pmask : integer := 16#fff#;
vgamst : integer := 0;
vgaburst : integer := 0
);
port(
mcb3_dram_dq : inout std_logic_vector(15 downto 0);
mcb3_dram_a : out std_logic_vector(12 downto 0);
mcb3_dram_ba : out std_logic_vector(2 downto 0);
mcb3_dram_ras_n : out std_logic;
mcb3_dram_cas_n : out std_logic;
mcb3_dram_we_n : out std_logic;
mcb3_dram_odt : out std_logic;
mcb3_dram_reset_n : out std_logic;
mcb3_dram_cke : out std_logic;
mcb3_dram_dm : out std_logic;
mcb3_dram_udqs : inout std_logic;
mcb3_dram_udqs_n : inout std_logic;
mcb3_rzq : inout std_logic;
mcb3_zio : inout std_logic;
mcb3_dram_udm : out std_logic;
mcb3_dram_dqs : inout std_logic;
mcb3_dram_dqs_n : inout std_logic;
mcb3_dram_ck : out std_logic;
mcb3_dram_ck_n : out std_logic;
ahbso : out ahb_slv_out_type;
ahbsi : in ahb_slv_in_type;
ahbmi : out ahb_mst_in_type;
ahbmo : in ahb_mst_out_type;
apbi : in apb_slv_in_type;
apbo : out apb_slv_out_type;
calib_done : out std_logic;
rst_n_syn : in std_logic;
rst_n_async : in std_logic;
clk_amba : in std_logic;
clk_mem_p : in std_logic;
clk_mem_n : in std_logic;
clk_125 : out std_logic;
clk_50 : out std_logic
);
end ;
architecture rtl of ahb2mig_sp605 is
type bstate_type is (idle, start, read1);
constant hconfig : ahb_config_type := (
0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_MIGDDR2, 0, 0, 0),
4 => ahb_membar(haddr, '1', '1', hmask),
-- 5 => ahb_iobar(ioaddr, iomask),
others => zero32);
constant pconfig : apb_config_type := (
0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_MIGDDR2, 0, 0, 0),
1 => apb_iobar(paddr, pmask));
type reg_type is record
bstate : bstate_type;
cmd_bl : std_logic_vector(5 downto 0);
wr_count : std_logic_vector(6 downto 0);
rd_cnt : std_logic_vector(5 downto 0);
hready : std_logic;
hsel : std_logic;
hwrite : std_logic;
htrans : std_logic_vector(1 downto 0);
hburst : std_logic_vector(2 downto 0);
hsize : std_logic_vector(2 downto 0);
hrdata : std_logic_vector(31 downto 0);
haddr : std_logic_vector(31 downto 0);
hmaster : std_logic_vector(3 downto 0);
end record;
type mcb_type is record
cmd_en : std_logic;
cmd_instr : std_logic_vector(2 downto 0);
cmd_empty : std_logic;
cmd_full : std_logic;
cmd_bl : std_logic_vector(5 downto 0);
cmd_byte_addr : std_logic_vector(29 downto 0);
wr_full : std_logic;
wr_empty : std_logic;
wr_underrun : std_logic;
wr_error : std_logic;
wr_mask : std_logic_vector(3 downto 0);
wr_en : std_logic;
wr_data : std_logic_vector(31 downto 0);
wr_count : std_logic_vector(6 downto 0);
rd_data : std_logic_vector(31 downto 0);
rd_full : std_logic;
rd_empty : std_logic;
rd_count : std_logic_vector(6 downto 0);
rd_overflow : std_logic;
rd_error : std_logic;
rd_en : std_logic;
end record;
type reg2_type is record
bstate : bstate_type;
cmd_bl : std_logic_vector(5 downto 0);
rd_cnt : std_logic_vector(5 downto 0);
hready : std_logic;
hsel : std_logic;
hrdata : std_logic_vector(31 downto 0);
haddr : std_logic_vector(31 downto 0);
end record;
type p2_if_type is record
cmd_en : std_logic;
cmd_instr : std_logic_vector(2 downto 0);
cmd_bl : std_logic_vector(5 downto 0);
cmd_empty : std_logic;
cmd_full : std_logic;
rd_en : std_logic;
rd_data : std_logic_vector(31 downto 0);
rd_full : std_logic;
rd_empty : std_logic;
rd_count : std_logic_vector(6 downto 0);
rd_overflow : std_logic;
rd_error : std_logic;
end record;
signal r, rin : reg_type;
signal r2, r2in : reg2_type;
signal i : mcb_type;
signal p2 : p2_if_type;
begin
comb: process( rst_n_syn, r, ahbsi, i )
variable v : reg_type;
variable wmask : std_logic_vector(3 downto 0);
variable wr_en : std_logic;
variable cmd_en : std_logic;
variable cmd_instr : std_logic_vector(2 downto 0);
variable rd_en : std_logic;
variable cmd_bl : std_logic_vector(5 downto 0);
variable hwdata : std_logic_vector(31 downto 0);
variable readdata : std_logic_vector(31 downto 0);
begin
v := r; wr_en := '0'; cmd_en := '0'; cmd_instr := "000";
rd_en := '0';
if (ahbsi.hready = '1') then
if (ahbsi.hsel(hindex) and ahbsi.htrans(1)) = '1' then
v.hsel := '1'; v.hburst := ahbsi.hburst;
v.hwrite := ahbsi.hwrite; v.hsize := ahbsi.hsize;
v.hmaster := ahbsi.hmaster;
v.hready := '0';
if ahbsi.htrans(0) = '0' then v.haddr := ahbsi.haddr; end if;
else
v.hsel := '0'; v.hready := '1';
end if;
v.htrans := ahbsi.htrans;
end if;
hwdata := ahbsi.hwdata(15 downto 0) & ahbsi.hwdata(31 downto 16);
case r.hsize(1 downto 0) is
when "00" => wmask := not decode(r.haddr(1 downto 0));
case r.haddr(1 downto 0) is
when "00" => wmask := "1101";
when "01" => wmask := "1110";
when "10" => wmask := "0111";
when others => wmask := "1011";
end case;
when "01" => wmask := not decode(r.haddr(1 downto 0));
wmask(3) := wmask(2); wmask(1) := wmask(0);
when others => wmask := "0000";
end case;
i.wr_mask <= wmask;
cmd_bl := r.cmd_bl;
case r.bstate is
when idle =>
if v.hsel = '1' then
v.bstate := start;
v.hready := ahbsi.hwrite and not i.cmd_full and not i.wr_full;
v.haddr := ahbsi.haddr;
end if;
v.cmd_bl := (others => '0');
when start =>
if r.hwrite = '1' then
v.haddr := r.haddr;
if r.hready = '1' then
v.cmd_bl := r.cmd_bl + 1; v.hready := '1'; wr_en := '1';
if (ahbsi.htrans /= "11") then
if v.hsel = '1' then
if (ahbsi.hwrite = '0') or (i.wr_count >= "0000100") then
v.hready := '0';
else v.hready := '1'; end if;
else v.bstate := idle; end if;
v.cmd_bl := (others => '0'); v.haddr := ahbsi.haddr;
cmd_en := '1';
elsif (i.cmd_full = '1') then
v.hready := '0';
elsif (i.wr_count >= "0101111") then
v.hready := '0'; cmd_en := '1';
v.cmd_bl := (others => '0'); v.haddr := ahbsi.haddr;
end if;
else
if (i.cmd_full = '0') and (i.wr_count <= "0001111") then
v.hready := '1';
end if;
end if;
else
if i.cmd_full = '0' then
cmd_en := '1'; cmd_instr(0) := '1';
v.cmd_bl := "000" & not r.haddr(4 downto 2);
cmd_bl := v.cmd_bl;
v.bstate := read1;
end if;
end if;
when read1 =>
v.hready := '0';
if (r.rd_cnt = "000000") then -- flush data from previous line
if (i.rd_empty = '0') or ((r.hready = '1') and (ahbsi.htrans /= "11")) then
v.hrdata(31 downto 0) := i.rd_data(15 downto 0) & i.rd_data(31 downto 16);
v.hready := '1';
if (i.rd_empty = '0') then v.cmd_bl := r.cmd_bl - 1; rd_en := '1'; end if;
if (r.cmd_bl = "000000") or (ahbsi.htrans /= "11") then
if (ahbsi.hsel(hindex) = '1') and (ahbsi.htrans = "10") and (r.hready = '1') then
v.bstate := start; v.hready := ahbsi.hwrite and not i.cmd_full and not i.wr_full;
v.cmd_bl := (others => '0');
else
v.bstate := idle;
end if;
if (i.rd_empty = '1') then v.rd_cnt := r.cmd_bl + 1;
else v.rd_cnt := r.cmd_bl; end if;
end if;
end if;
end if;
when others =>
end case;
readdata := (others => '0');
-- case apbi.paddr(5 downto 2) is
-- when "0000" => readdata(nbits-1 downto 0) := r.din2;
-- when "0001" => readdata(nbits-1 downto 0) := r.dout;
-- when others =>
-- end case;
readdata(20 downto 0) :=
i.rd_error & i.rd_overflow & i.wr_error & i.wr_underrun &
i.cmd_full & i.rd_full & i.rd_empty & i.wr_full & i.wr_empty &
r.rd_cnt & r.cmd_bl;
if (r.rd_cnt /= "000000") and (i.rd_empty = '0') then
rd_en := '1'; v.rd_cnt := r.rd_cnt - 1;
end if;
if rst_n_syn = '0' then
v.rd_cnt := "000000"; v.bstate := idle; v.hready := '1';
end if;
rin <= v;
apbo.prdata <= readdata;
i.rd_en <= rd_en;
i.wr_en <= wr_en;
i.cmd_bl <= cmd_bl;
i.cmd_en <= cmd_en;
i.cmd_instr <= cmd_instr;
i.wr_data <= hwdata;
end process;
i.cmd_byte_addr <= r.haddr(29 downto 2) & "00";
ahbso.hready <= r.hready;
ahbso.hresp <= "00"; --r.hresp;
ahbso.hrdata <= r.hrdata;
ahbso.hconfig <= hconfig;
ahbso.hirq <= (others => '0');
ahbso.hindex <= hindex;
ahbso.hsplit <= (others => '0');
ahbso.hcache <= '1';
apbo.pindex <= pindex;
apbo.pconfig <= pconfig;
apbo.pirq <= (others => '0');
regs : process(clk_amba)
begin
if rising_edge(clk_amba) then
r <= rin;
end if;
end process;
port2 : if vgamst /= 0 generate
comb2: process( rst_n_syn, r2, ahbmo, p2 )
variable v2 : reg2_type;
variable cmd_en : std_logic;
variable rd_en : std_logic;
begin
v2 := r2; cmd_en := '0'; rd_en := '0';
case r2.bstate is
when idle =>
if ahbmo.htrans(1) = '1' then
v2.bstate := start;
v2.hready := '0';
v2.haddr := ahbmo.haddr;
else v2.hready := '1'; end if;
v2.cmd_bl := (others => '0');
when start =>
if p2.cmd_full = '0' then
cmd_en := '1';
v2.cmd_bl := conv_std_logic_vector(vgaburst-1, 6);
v2.bstate := read1;
end if;
when read1 =>
v2.hready := '0';
if (r2.rd_cnt = "000000") then -- flush data from previous line
if (p2.rd_empty = '0') or ((r2.hready = '1') and (ahbmo.htrans /= "11")) then
v2.hrdata(31 downto 0) := p2.rd_data(15 downto 0) & p2.rd_data(31 downto 16);
v2.hready := '1';
if (p2.rd_empty = '0') then v2.cmd_bl := r2.cmd_bl - 1; rd_en := '1'; end if;
if (r2.cmd_bl = "000000") or (ahbmo.htrans /= "11") then
if (ahbmo.htrans = "10") and (r2.hready = '1') then
v2.bstate := start; v2.hready := '0';
v2.cmd_bl := (others => '0');
else
v2.bstate := idle;
end if;
if (p2.rd_empty = '1') then v2.rd_cnt := r2.cmd_bl + 1;
else v2.rd_cnt := r2.cmd_bl; end if;
end if;
end if;
end if;
when others =>
end case;
if (r2.rd_cnt /= "000000") and (p2.rd_empty = '0') then
rd_en := '1'; v2.rd_cnt := r2.rd_cnt - 1;
end if;
v2.haddr(1 downto 0) := "00";
if rst_n_syn = '0' then
v2.rd_cnt := "000000"; v2.bstate := idle; v2.hready := '1';
end if;
r2in <= v2;
p2.rd_en <= rd_en;
p2.cmd_bl <= v2.cmd_bl;
p2.cmd_en <= cmd_en;
p2.cmd_instr <= "001";
end process;
ahbmi.hrdata <= r2.hrdata;
ahbmi.hresp <= "00";
ahbmi.hgrant <= (others => '1');
ahbmi.hready <= r2.hready;
ahbmi.hcache <= '0';
ahbmi.hirq <= (others => '0');
ahbmi.testen <= '0';
ahbmi.testrst <= '0';
ahbmi.scanen <= '0';
ahbmi.testoen <= '0';
regs : process(clk_amba)
begin
if rising_edge(clk_amba) then
r2 <= r2in;
end if;
end process;
end generate;
noport2 : if vgamst = 0 generate
p2.cmd_en <= '0';
p2.rd_en <= '0';
end generate;
MCB_inst : entity work.mig_38 generic map(
C3_P0_MASK_SIZE => 4,
C3_P0_DATA_PORT_SIZE => 32,
C3_P1_MASK_SIZE => 4,
C3_P1_DATA_PORT_SIZE => 32,
-- C3_MEMCLK_PERIOD => 5000,
C3_RST_ACT_LOW => 1,
C3_INPUT_CLK_TYPE => "DIFFERENTIAL",
C3_CALIB_SOFT_IP => "TRUE",
-- pragma translate_off
C3_SIMULATION => "TRUE",
-- pragma translate_on
C3_MEM_ADDR_ORDER => "BANK_ROW_COLUMN",
C3_NUM_DQ_PINS => 16,
C3_MEM_ADDR_WIDTH => 13,
C3_MEM_BANKADDR_WIDTH => 3
)
port map (
mcb3_dram_dq => mcb3_dram_dq,
mcb3_dram_a => mcb3_dram_a,
mcb3_dram_ba => mcb3_dram_ba,
mcb3_dram_ras_n => mcb3_dram_ras_n,
mcb3_dram_cas_n => mcb3_dram_cas_n,
mcb3_dram_we_n => mcb3_dram_we_n,
mcb3_dram_odt => mcb3_dram_odt,
mcb3_dram_reset_n => mcb3_dram_reset_n,
mcb3_dram_cke => mcb3_dram_cke,
mcb3_dram_dm => mcb3_dram_dm,
mcb3_dram_udqs => mcb3_dram_udqs,
mcb3_dram_udqs_n => mcb3_dram_udqs_n,
mcb3_rzq => mcb3_rzq,
mcb3_zio => mcb3_zio,
mcb3_dram_udm => mcb3_dram_udm,
c3_sys_clk_p => clk_mem_p,
c3_sys_clk_n => clk_mem_n,
c3_sys_rst_i => rst_n_async,
c3_calib_done => calib_done,
c3_clk0 => open,
c3_rst0 => open,
mcb3_dram_dqs => mcb3_dram_dqs,
mcb3_dram_dqs_n => mcb3_dram_dqs_n,
mcb3_dram_ck => mcb3_dram_ck,
mcb3_dram_ck_n => mcb3_dram_ck_n,
c3_p0_cmd_clk => clk_amba,
c3_p0_cmd_en => i.cmd_en,
c3_p0_cmd_instr => i.cmd_instr,
c3_p0_cmd_bl => i.cmd_bl,
c3_p0_cmd_byte_addr => i.cmd_byte_addr,
c3_p0_cmd_empty => i.cmd_empty,
c3_p0_cmd_full => i.cmd_full,
c3_p0_wr_clk => clk_amba,
c3_p0_wr_en => i.wr_en,
c3_p0_wr_mask => i.wr_mask,
c3_p0_wr_data => i.wr_data,
c3_p0_wr_full => i.wr_full,
c3_p0_wr_empty => i.wr_empty,
c3_p0_wr_count => i.wr_count,
c3_p0_wr_underrun => i.wr_underrun,
c3_p0_wr_error => i.wr_error,
c3_p0_rd_clk => clk_amba,
c3_p0_rd_en => i.rd_en,
c3_p0_rd_data => i.rd_data,
c3_p0_rd_full => i.rd_full,
c3_p0_rd_empty => i.rd_empty,
c3_p0_rd_count => i.rd_count,
c3_p0_rd_overflow => i.rd_overflow,
c3_p0_rd_error => i.rd_error,
c3_p2_cmd_clk => clk_amba,
c3_p2_cmd_en => p2.cmd_en,
c3_p2_cmd_instr => p2.cmd_instr,
c3_p2_cmd_bl => p2.cmd_bl,
c3_p2_cmd_byte_addr => r2.haddr(29 downto 0),
c3_p2_cmd_empty => p2.cmd_empty,
c3_p2_cmd_full => p2.cmd_full,
c3_p2_rd_clk => clk_amba,
c3_p2_rd_en => p2.rd_en,
c3_p2_rd_data => p2.rd_data,
c3_p2_rd_full => p2.rd_full,
c3_p2_rd_empty => p2.rd_empty,
c3_p2_rd_count => p2.rd_count,
c3_p2_rd_overflow => p2.rd_overflow,
c3_p2_rd_error => p2.rd_error,
clk_125 => clk_125,
clk_50 => clk_50
);
end;