From 06e62e21a3c9792730e45c53f71f702857fe78b6 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Wed, 2 Sep 2009 09:17:59 +0000 Subject: [PATCH] *** empty log message *** --- lattice/ecp2m/slv_spi_dpram.jhd | 1 + lattice/ecp2m/slv_spi_dpram.lpc | 57 +++ lattice/ecp2m/slv_spi_dpram.srp | 28 ++ lattice/ecp2m/slv_spi_dpram.vhd | 252 ++++++++++++ special/slv_spi_memory.vhd | 165 ++++++++ special/spi_master.vhd | 246 ++++++++++++ special/spi_slim.vhd | 666 ++++++++++++++++++++++++++++++++ trb_net16_hub_ipu_logic.vhd | 82 ++-- trb_net16_regIO.vhd | 6 +- 9 files changed, 1478 insertions(+), 25 deletions(-) create mode 100755 lattice/ecp2m/slv_spi_dpram.jhd create mode 100755 lattice/ecp2m/slv_spi_dpram.lpc create mode 100755 lattice/ecp2m/slv_spi_dpram.srp create mode 100755 lattice/ecp2m/slv_spi_dpram.vhd create mode 100755 special/slv_spi_memory.vhd create mode 100755 special/spi_master.vhd create mode 100755 special/spi_slim.vhd diff --git a/lattice/ecp2m/slv_spi_dpram.jhd b/lattice/ecp2m/slv_spi_dpram.jhd new file mode 100755 index 0000000..23cd391 --- /dev/null +++ b/lattice/ecp2m/slv_spi_dpram.jhd @@ -0,0 +1 @@ +MODULE slv_spi_dpram diff --git a/lattice/ecp2m/slv_spi_dpram.lpc b/lattice/ecp2m/slv_spi_dpram.lpc new file mode 100755 index 0000000..0dd45ab --- /dev/null +++ b/lattice/ecp2m/slv_spi_dpram.lpc @@ -0,0 +1,57 @@ +[Device] +Family=latticeecp2m +PartType=LFE2M100E +PartName=LFE2M100E-6F900C +SpeedGrade=-6 +Package=FPBGA900 +OperatingCondition=COM +Status=P + +[IP] +VendorName=Lattice Semiconductor Corporation +CoreType=LPM +CoreStatus=Demo +CoreName=RAM_DP_TRUE +CoreRevision=7.1 +ModuleName=slv_spi_dpram +SourceFormat=VHDL +ParameterFileVersion=1.0 +Date=08/24/2009 +Time=13:18:12 + +[Parameters] +Verilog=0 +VHDL=1 +EDIF=1 +Destination=Synplicity +Expression=BusA(0 to 7) +Order=Big Endian [MSB:LSB] +IO=0 +AAddress=64 +BAddress=256 +AData=32 +BData=8 +enByte=0 +ByteSize=9 +AadPipeline=0 +BadPipeline=0 +AinPipeline=0 +BinPipeline=0 +AoutPipeline=0 +BoutPipeline=0 +AMOR=0 +BMOR=0 +AInData=Registered +BInData=Registered +AAdControl=Registered +BAdControl=Registered +MemFile= +MemFormat=bin +Reset=Sync +GSR=Enabled +WriteA=Normal +WriteB=Normal +Pad=0 +EnECC=0 +Optimization=Speed +Pipeline=0 diff --git a/lattice/ecp2m/slv_spi_dpram.srp b/lattice/ecp2m/slv_spi_dpram.srp new file mode 100755 index 0000000..bd91c46 --- /dev/null +++ b/lattice/ecp2m/slv_spi_dpram.srp @@ -0,0 +1,28 @@ +SCUBA, Version ispLever_v72_SP2_Build (23) +Mon Aug 24 13:18:12 2009 + +Copyright (c) 1991-1994 by NeoCAD Inc. All rights reserved. +Copyright (c) 1995 AT&T Corp. All rights reserved. +Copyright (c) 1995-2001 Lucent Technologies Inc. All rights reserved. +Copyright (c) 2001 Agere Systems All rights reserved. +Copyright (c) 2002-2008 Lattice Semiconductor Corporation, All rights reserved. + + Issued command : X:\Programme\ispTOOLS_72\ispfpga\bin\nt\scuba.exe -w -n slv_spi_dpram -lang vhdl -synth synplify -bus_exp 7 -bb -arch ep5m00 -type ramdp -device LFE2M100E -aaddr_width 6 -widtha 32 -baddr_width 8 -widthb 8 -anum_words 64 -bnum_words 256 -writemodeA NORMAL -writemodeB NORMAL -resetmode SYNC -cascade -1 -e + Circuit name : slv_spi_dpram + Module type : RAM_DP_TRUE + Module Version : 7.1 + Ports : + Inputs : DataInA[31:0], DataInB[7:0], AddressA[5:0], AddressB[7:0], ClockA, ClockB, ClockEnA, ClockEnB, WrA, WrB, ResetA, ResetB + Outputs : QA[31:0], QB[7:0] + I/O buffer : not inserted + EDIF output : suppressed + VHDL output : slv_spi_dpram.vhd + VHDL template : slv_spi_dpram_tmpl.vhd + VHDL testbench : tb_slv_spi_dpram_tmpl.vhd + VHDL purpose : for synthesis and simulation + Bus notation : big endian + Report output : slv_spi_dpram.srp + Element Usage : + DP16KB : 2 + Estimated Resource Usage: + EBR : 2 diff --git a/lattice/ecp2m/slv_spi_dpram.vhd b/lattice/ecp2m/slv_spi_dpram.vhd new file mode 100755 index 0000000..b79dc15 --- /dev/null +++ b/lattice/ecp2m/slv_spi_dpram.vhd @@ -0,0 +1,252 @@ +-- VHDL netlist generated by SCUBA ispLever_v72_SP2_Build (23) +-- Module Version: 7.1 +--X:\Programme\ispTOOLS_72\ispfpga\bin\nt\scuba.exe -w -lang vhdl -synth synplify -bus_exp 7 -bb -arch ep5m00 -type bram -wp 11 -rp 1010 -data_width 32 -rdata_width 8 -num_rows 64 -writemodeA NORMAL -writemodeB NORMAL -resetmode SYNC -cascade -1 -e + +-- Mon Aug 24 13:18:12 2009 + +library IEEE; +use IEEE.std_logic_1164.all; +-- synopsys translate_off +library ecp2m; +use ecp2m.components.all; +-- synopsys translate_on + +entity slv_spi_dpram is + port ( + DataInA: in std_logic_vector(31 downto 0); + DataInB: in std_logic_vector(7 downto 0); + AddressA: in std_logic_vector(5 downto 0); + AddressB: in std_logic_vector(7 downto 0); + ClockA: in std_logic; + ClockB: in std_logic; + ClockEnA: in std_logic; + ClockEnB: in std_logic; + WrA: in std_logic; + WrB: in std_logic; + ResetA: in std_logic; + ResetB: in std_logic; + QA: out std_logic_vector(31 downto 0); + QB: out std_logic_vector(7 downto 0)); +end slv_spi_dpram; + +architecture Structure of slv_spi_dpram is + + -- internal signal declarations + signal scuba_vhi: std_logic; + signal scuba_vlo: std_logic; + + -- local component declarations + component VHI + port (Z: out std_logic); + end component; + component VLO + port (Z: out std_logic); + end component; + component DP16KB + -- synopsys translate_off + generic (GSR : in String; WRITEMODE_B : in String; + CSDECODE_B : in std_logic_vector(2 downto 0); + CSDECODE_A : in std_logic_vector(2 downto 0); + WRITEMODE_A : in String; RESETMODE : in String; + REGMODE_B : in String; REGMODE_A : in String; + DATA_WIDTH_B : in Integer; DATA_WIDTH_A : in Integer); + -- synopsys translate_on + port (DIA0: in std_logic; DIA1: in std_logic; + DIA2: in std_logic; DIA3: in std_logic; + DIA4: in std_logic; DIA5: in std_logic; + DIA6: in std_logic; DIA7: in std_logic; + DIA8: in std_logic; DIA9: in std_logic; + DIA10: in std_logic; DIA11: in std_logic; + DIA12: in std_logic; DIA13: in std_logic; + DIA14: in std_logic; DIA15: in std_logic; + DIA16: in std_logic; DIA17: in std_logic; + ADA0: in std_logic; ADA1: in std_logic; + ADA2: in std_logic; ADA3: in std_logic; + ADA4: in std_logic; ADA5: in std_logic; + ADA6: in std_logic; ADA7: in std_logic; + ADA8: in std_logic; ADA9: in std_logic; + ADA10: in std_logic; ADA11: in std_logic; + ADA12: in std_logic; ADA13: in std_logic; + CEA: in std_logic; CLKA: in std_logic; WEA: in std_logic; + CSA0: in std_logic; CSA1: in std_logic; + CSA2: in std_logic; RSTA: in std_logic; + DIB0: in std_logic; DIB1: in std_logic; + DIB2: in std_logic; DIB3: in std_logic; + DIB4: in std_logic; DIB5: in std_logic; + DIB6: in std_logic; DIB7: in std_logic; + DIB8: in std_logic; DIB9: in std_logic; + DIB10: in std_logic; DIB11: in std_logic; + DIB12: in std_logic; DIB13: in std_logic; + DIB14: in std_logic; DIB15: in std_logic; + DIB16: in std_logic; DIB17: in std_logic; + ADB0: in std_logic; ADB1: in std_logic; + ADB2: in std_logic; ADB3: in std_logic; + ADB4: in std_logic; ADB5: in std_logic; + ADB6: in std_logic; ADB7: in std_logic; + ADB8: in std_logic; ADB9: in std_logic; + ADB10: in std_logic; ADB11: in std_logic; + ADB12: in std_logic; ADB13: in std_logic; + CEB: in std_logic; CLKB: in std_logic; WEB: in std_logic; + CSB0: in std_logic; CSB1: in std_logic; + CSB2: in std_logic; RSTB: in std_logic; + DOA0: out std_logic; DOA1: out std_logic; + DOA2: out std_logic; DOA3: out std_logic; + DOA4: out std_logic; DOA5: out std_logic; + DOA6: out std_logic; DOA7: out std_logic; + DOA8: out std_logic; DOA9: out std_logic; + DOA10: out std_logic; DOA11: out std_logic; + DOA12: out std_logic; DOA13: out std_logic; + DOA14: out std_logic; DOA15: out std_logic; + DOA16: out std_logic; DOA17: out std_logic; + DOB0: out std_logic; DOB1: out std_logic; + DOB2: out std_logic; DOB3: out std_logic; + DOB4: out std_logic; DOB5: out std_logic; + DOB6: out std_logic; DOB7: out std_logic; + DOB8: out std_logic; DOB9: out std_logic; + DOB10: out std_logic; DOB11: out std_logic; + DOB12: out std_logic; DOB13: out std_logic; + DOB14: out std_logic; DOB15: out std_logic; + DOB16: out std_logic; DOB17: out std_logic); + end component; + attribute MEM_LPC_FILE : string; + attribute MEM_INIT_FILE : string; + attribute CSDECODE_B : string; + attribute CSDECODE_A : string; + attribute WRITEMODE_B : string; + attribute WRITEMODE_A : string; + attribute GSR : string; + attribute RESETMODE : string; + attribute REGMODE_B : string; + attribute REGMODE_A : string; + attribute DATA_WIDTH_B : string; + attribute DATA_WIDTH_A : string; + attribute MEM_LPC_FILE of slv_spi_dpram_0_0_1 : label is "slv_spi_dpram.lpc"; + attribute MEM_INIT_FILE of slv_spi_dpram_0_0_1 : label is ""; + attribute CSDECODE_B of slv_spi_dpram_0_0_1 : label is "0b000"; + attribute CSDECODE_A of slv_spi_dpram_0_0_1 : label is "0b000"; + attribute WRITEMODE_B of slv_spi_dpram_0_0_1 : label is "NORMAL"; + attribute WRITEMODE_A of slv_spi_dpram_0_0_1 : label is "NORMAL"; + attribute GSR of slv_spi_dpram_0_0_1 : label is "DISABLED"; + attribute RESETMODE of slv_spi_dpram_0_0_1 : label is "SYNC"; + attribute REGMODE_B of slv_spi_dpram_0_0_1 : label is "NOREG"; + attribute REGMODE_A of slv_spi_dpram_0_0_1 : label is "NOREG"; + attribute DATA_WIDTH_B of slv_spi_dpram_0_0_1 : label is "4"; + attribute DATA_WIDTH_A of slv_spi_dpram_0_0_1 : label is "18"; + attribute MEM_LPC_FILE of slv_spi_dpram_0_1_0 : label is "slv_spi_dpram.lpc"; + attribute MEM_INIT_FILE of slv_spi_dpram_0_1_0 : label is ""; + attribute CSDECODE_B of slv_spi_dpram_0_1_0 : label is "0b000"; + attribute CSDECODE_A of slv_spi_dpram_0_1_0 : label is "0b000"; + attribute WRITEMODE_B of slv_spi_dpram_0_1_0 : label is "NORMAL"; + attribute WRITEMODE_A of slv_spi_dpram_0_1_0 : label is "NORMAL"; + attribute GSR of slv_spi_dpram_0_1_0 : label is "DISABLED"; + attribute RESETMODE of slv_spi_dpram_0_1_0 : label is "SYNC"; + attribute REGMODE_B of slv_spi_dpram_0_1_0 : label is "NOREG"; + attribute REGMODE_A of slv_spi_dpram_0_1_0 : label is "NOREG"; + attribute DATA_WIDTH_B of slv_spi_dpram_0_1_0 : label is "4"; + attribute DATA_WIDTH_A of slv_spi_dpram_0_1_0 : label is "18"; + +begin + -- component instantiation statements + slv_spi_dpram_0_0_1: DP16KB + -- synopsys translate_off + generic map (CSDECODE_B=> "000", CSDECODE_A=> "000", WRITEMODE_B=> "NORMAL", + WRITEMODE_A=> "NORMAL", GSR=> "DISABLED", RESETMODE=> "SYNC", + REGMODE_B=> "NOREG", REGMODE_A=> "NOREG", DATA_WIDTH_B=> 4, + DATA_WIDTH_A=> 18) + -- synopsys translate_on + port map (DIA0=>DataInA(0), DIA1=>DataInA(1), DIA2=>DataInA(2), + DIA3=>DataInA(3), DIA4=>DataInA(8), DIA5=>DataInA(9), + DIA6=>DataInA(10), DIA7=>DataInA(11), DIA8=>scuba_vlo, + DIA9=>DataInA(16), DIA10=>DataInA(17), DIA11=>DataInA(18), + DIA12=>DataInA(19), DIA13=>DataInA(24), DIA14=>DataInA(25), + DIA15=>DataInA(26), DIA16=>DataInA(27), DIA17=>scuba_vlo, + ADA0=>scuba_vhi, ADA1=>scuba_vhi, ADA2=>scuba_vlo, + ADA3=>scuba_vlo, ADA4=>AddressA(0), ADA5=>AddressA(1), + ADA6=>AddressA(2), ADA7=>AddressA(3), ADA8=>AddressA(4), + ADA9=>AddressA(5), ADA10=>scuba_vlo, ADA11=>scuba_vlo, + ADA12=>scuba_vlo, ADA13=>scuba_vlo, CEA=>ClockEnA, + CLKA=>ClockA, WEA=>WrA, CSA0=>scuba_vlo, CSA1=>scuba_vlo, + CSA2=>scuba_vlo, RSTA=>ResetA, DIB0=>DataInB(0), + DIB1=>DataInB(1), DIB2=>DataInB(2), DIB3=>DataInB(3), + DIB4=>scuba_vlo, DIB5=>scuba_vlo, DIB6=>scuba_vlo, + DIB7=>scuba_vlo, DIB8=>scuba_vlo, DIB9=>scuba_vlo, + DIB10=>scuba_vlo, DIB11=>scuba_vlo, DIB12=>scuba_vlo, + DIB13=>scuba_vlo, DIB14=>scuba_vlo, DIB15=>scuba_vlo, + DIB16=>scuba_vlo, DIB17=>scuba_vlo, ADB0=>scuba_vlo, + ADB1=>scuba_vlo, ADB2=>AddressB(0), ADB3=>AddressB(1), + ADB4=>AddressB(2), ADB5=>AddressB(3), ADB6=>AddressB(4), + ADB7=>AddressB(5), ADB8=>AddressB(6), ADB9=>AddressB(7), + ADB10=>scuba_vlo, ADB11=>scuba_vlo, ADB12=>scuba_vlo, + ADB13=>scuba_vlo, CEB=>ClockEnB, CLKB=>ClockB, WEB=>WrB, + CSB0=>scuba_vlo, CSB1=>scuba_vlo, CSB2=>scuba_vlo, + RSTB=>ResetB, DOA0=>QA(0), DOA1=>QA(1), DOA2=>QA(2), + DOA3=>QA(3), DOA4=>QA(8), DOA5=>QA(9), DOA6=>QA(10), + DOA7=>QA(11), DOA8=>open, DOA9=>QA(16), DOA10=>QA(17), + DOA11=>QA(18), DOA12=>QA(19), DOA13=>QA(24), DOA14=>QA(25), + DOA15=>QA(26), DOA16=>QA(27), DOA17=>open, DOB0=>QB(0), + DOB1=>QB(1), DOB2=>QB(2), DOB3=>QB(3), DOB4=>open, + DOB5=>open, DOB6=>open, DOB7=>open, DOB8=>open, DOB9=>open, + DOB10=>open, DOB11=>open, DOB12=>open, DOB13=>open, + DOB14=>open, DOB15=>open, DOB16=>open, DOB17=>open); + + scuba_vhi_inst: VHI + port map (Z=>scuba_vhi); + + scuba_vlo_inst: VLO + port map (Z=>scuba_vlo); + + slv_spi_dpram_0_1_0: DP16KB + -- synopsys translate_off + generic map (CSDECODE_B=> "000", CSDECODE_A=> "000", WRITEMODE_B=> "NORMAL", + WRITEMODE_A=> "NORMAL", GSR=> "DISABLED", RESETMODE=> "SYNC", + REGMODE_B=> "NOREG", REGMODE_A=> "NOREG", DATA_WIDTH_B=> 4, + DATA_WIDTH_A=> 18) + -- synopsys translate_on + port map (DIA0=>DataInA(4), DIA1=>DataInA(5), DIA2=>DataInA(6), + DIA3=>DataInA(7), DIA4=>DataInA(12), DIA5=>DataInA(13), + DIA6=>DataInA(14), DIA7=>DataInA(15), DIA8=>scuba_vlo, + DIA9=>DataInA(20), DIA10=>DataInA(21), DIA11=>DataInA(22), + DIA12=>DataInA(23), DIA13=>DataInA(28), DIA14=>DataInA(29), + DIA15=>DataInA(30), DIA16=>DataInA(31), DIA17=>scuba_vlo, + ADA0=>scuba_vhi, ADA1=>scuba_vhi, ADA2=>scuba_vlo, + ADA3=>scuba_vlo, ADA4=>AddressA(0), ADA5=>AddressA(1), + ADA6=>AddressA(2), ADA7=>AddressA(3), ADA8=>AddressA(4), + ADA9=>AddressA(5), ADA10=>scuba_vlo, ADA11=>scuba_vlo, + ADA12=>scuba_vlo, ADA13=>scuba_vlo, CEA=>ClockEnA, + CLKA=>ClockA, WEA=>WrA, CSA0=>scuba_vlo, CSA1=>scuba_vlo, + CSA2=>scuba_vlo, RSTA=>ResetA, DIB0=>DataInB(4), + DIB1=>DataInB(5), DIB2=>DataInB(6), DIB3=>DataInB(7), + DIB4=>scuba_vlo, DIB5=>scuba_vlo, DIB6=>scuba_vlo, + DIB7=>scuba_vlo, DIB8=>scuba_vlo, DIB9=>scuba_vlo, + DIB10=>scuba_vlo, DIB11=>scuba_vlo, DIB12=>scuba_vlo, + DIB13=>scuba_vlo, DIB14=>scuba_vlo, DIB15=>scuba_vlo, + DIB16=>scuba_vlo, DIB17=>scuba_vlo, ADB0=>scuba_vlo, + ADB1=>scuba_vlo, ADB2=>AddressB(0), ADB3=>AddressB(1), + ADB4=>AddressB(2), ADB5=>AddressB(3), ADB6=>AddressB(4), + ADB7=>AddressB(5), ADB8=>AddressB(6), ADB9=>AddressB(7), + ADB10=>scuba_vlo, ADB11=>scuba_vlo, ADB12=>scuba_vlo, + ADB13=>scuba_vlo, CEB=>ClockEnB, CLKB=>ClockB, WEB=>WrB, + CSB0=>scuba_vlo, CSB1=>scuba_vlo, CSB2=>scuba_vlo, + RSTB=>ResetB, DOA0=>QA(4), DOA1=>QA(5), DOA2=>QA(6), + DOA3=>QA(7), DOA4=>QA(12), DOA5=>QA(13), DOA6=>QA(14), + DOA7=>QA(15), DOA8=>open, DOA9=>QA(20), DOA10=>QA(21), + DOA11=>QA(22), DOA12=>QA(23), DOA13=>QA(28), DOA14=>QA(29), + DOA15=>QA(30), DOA16=>QA(31), DOA17=>open, DOB0=>QB(4), + DOB1=>QB(5), DOB2=>QB(6), DOB3=>QB(7), DOB4=>open, + DOB5=>open, DOB6=>open, DOB7=>open, DOB8=>open, DOB9=>open, + DOB10=>open, DOB11=>open, DOB12=>open, DOB13=>open, + DOB14=>open, DOB15=>open, DOB16=>open, DOB17=>open); + +end Structure; + +-- synopsys translate_off +library ecp2m; +configuration Structure_CON of slv_spi_dpram is + for Structure + for all:VHI use entity ecp2m.VHI(V); end for; + for all:VLO use entity ecp2m.VLO(V); end for; + for all:DP16KB use entity ecp2m.DP16KB(V); end for; + end for; +end Structure_CON; + +-- synopsys translate_on diff --git a/special/slv_spi_memory.vhd b/special/slv_spi_memory.vhd new file mode 100755 index 0000000..3f5c131 --- /dev/null +++ b/special/slv_spi_memory.vhd @@ -0,0 +1,165 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + + +entity slv_spi_memory is +port( CLK_IN : in std_logic; + CLEAR_IN : in std_logic; + RESET_IN : in std_logic; + -- Slave bus + SLV_ADDR_IN : in std_logic_vector(5 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- state machine connections + BRAM_ADDR_IN : in std_logic_vector(7 downto 0); + BRAM_WR_D_OUT : out std_logic_vector(7 downto 0); + BRAM_RD_D_IN : in std_logic_vector(7 downto 0); + BRAM_WE_IN : in std_logic; + -- Status lines + STAT : out std_logic_vector(63 downto 0) -- DEBUG + ); +end entity; + +architecture Behavioral of slv_spi_memory is + +-- Components + component slv_spi_dpram is + port( DATAINA : in std_logic_vector(31 downto 0); + DATAINB : in std_logic_vector(7 downto 0); + ADDRESSA : in std_logic_vector(5 downto 0); + ADDRESSB : in std_logic_vector(7 downto 0); + CLOCKA : in std_logic; + CLOCKB : in std_logic; + CLOCKENA : in std_logic; + CLOCKENB : in std_logic; + WRA : in std_logic; + WRB : in std_logic; + RESETA : in std_logic; + RESETB : in std_logic; + QA : out std_logic_vector(31 downto 0); + QB : out std_logic_vector(7 downto 0) + ); + end component; + +-- Signals + type STATES is (SLEEP,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + + -- slave bus signals + signal slv_ack_x : std_logic; + signal slv_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; + + signal wr_addr : std_logic_vector(6 downto 0); -- some bits are masked + signal wr_data : std_logic_vector(15 downto 0); + signal wr_we : std_logic; + signal buf_slv_data_out : std_logic_vector(31 downto 0); + + signal onewire_bsm : std_logic_vector(7 downto 0); + +begin + +-- Fake +stat(63 downto 0) <= (others => '0'); + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +-- State memory process +STATE_MEM: process( clk_in, clear_in ) +begin + if( clear_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + elsif( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + slv_ack <= slv_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; +end process STATE_MEM; + +-- Transition matrix +TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in ) +begin + NEXT_STATE <= SLEEP; + slv_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => if ( (slv_read_in = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (slv_write_in = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when RD_RDY => NEXT_STATE <= RD_ACK; + when WR_RDY => NEXT_STATE <= WR_ACK; + when RD_ACK => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + slv_ack_x <= '1'; + else + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + end if; + when WR_ACK => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + slv_ack_x <= '1'; + else + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + end if; + when DONE => NEXT_STATE <= SLEEP; + + when others => NEXT_STATE <= SLEEP; + end case; +end process TRANSFORM; + + +--------------------------------------------------------- +-- data handling -- +--------------------------------------------------------- + +THE_SLV_SPI_DPRAM: slv_spi_dpram +port map( DATAINA => slv_data_in, + ADDRESSA => slv_addr_in, + CLOCKA => clk_in, + CLOCKENA => '1', + WRA => store_wr, + RESETA => reset_in, + QA => buf_slv_data_out, + -- B side is state machine + DATAINB => bram_rd_d_in, + ADDRESSB => bram_addr_in, + CLOCKB => clk_in, + CLOCKENB => '1', + WRB => bram_we_in, + RESETB => reset_in, + QB => bram_wr_d_out + ); + +-- output signals +slv_data_out <= buf_slv_data_out; +slv_ack_out <= slv_ack; + +end Behavioral; diff --git a/special/spi_master.vhd b/special/spi_master.vhd new file mode 100755 index 0000000..76661b4 --- /dev/null +++ b/special/spi_master.vhd @@ -0,0 +1,246 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.adcmv2_components.all; + +entity spi_master is +port( CLK_IN : in std_logic; + CLEAR_IN : in std_logic; + RESET_IN : in std_logic; + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_ADDR_IN : in std_logic_vector(0 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- SPI connections + SPI_CS_OUT : out std_logic; + SPI_SDI_IN : in std_logic; + SPI_SDO_OUT : out std_logic; + SPI_SCK_OUT : out std_logic; + -- BRAM for read/write data + BRAM_A_OUT : out std_logic_vector(7 downto 0); + BRAM_WR_D_IN : in std_logic_vector(7 downto 0); + BRAM_RD_D_OUT : out std_logic_vector(7 downto 0); + BRAM_WE_OUT : out std_logic; + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG + ); +end entity; + +architecture Behavioral of spi_master is + +-- Modules + -- are now in adcmv2_components.vhd + +-- Signals + type STATES is (SLEEP,RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + + signal status_data : std_logic_vector(31 downto 0); + signal spi_busy : std_logic; + + signal reg_ctrl_data : std_logic_vector(31 downto 0); -- CMD, ADH, ADM, ADL + signal reg_status_data : std_logic_vector(31 downto 0); -- MAX + + signal reg_slv_data_out : std_logic_vector(31 downto 0); -- readback + + signal spi_bsm : std_logic_vector(7 downto 0); + + signal spi_start_x : std_logic; + signal spi_start : std_logic; + + -- State machine signals + signal slv_busy_x : std_logic; + signal slv_busy : std_logic; + signal slv_ack_x : std_logic; + signal slv_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; + +begin + +--------------------------------------------------------- +-- SPI master -- +--------------------------------------------------------- + +THE_SPI_SLIM: spi_slim +port map( SYSCLK => clk_in, + CLEAR => clear_in, + RESET => reset_in, + -- Command interface + START_IN => spi_start, -- not really nice, but should work + BUSY_OUT => spi_busy, + CMD_IN => reg_ctrl_data(31 downto 24), + ADH_IN => reg_ctrl_data(23 downto 16), + ADM_IN => reg_ctrl_data(15 downto 8), + ADL_IN => reg_ctrl_data(7 downto 0), + MAX_IN => reg_status_data(31 downto 24), + TXDATA_IN => bram_wr_d_in, + TX_RD_OUT => open, -- not needed + RXDATA_OUT => bram_rd_d_out, + RX_WR_OUT => bram_we_out, + TX_RX_A_OUT => bram_a_out, + -- SPI interface + SPI_SCK_OUT => spi_sck_out, + SPI_CS_OUT => spi_cs_out, + SPI_SDI_IN => spi_sdi_in, + SPI_SDO_OUT => spi_sdo_out, + -- DEBUG + CLK_EN_OUT => open, -- not needed + BSM_OUT => spi_bsm, + DEBUG_OUT => open -- BUG + ); + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +-- State memory process +STATE_MEM: process( clk_in, clear_in ) +begin + if( clear_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_busy <= '0'; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + elsif( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_busy <= '0'; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + slv_busy <= slv_busy_x; + slv_ack <= slv_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; +end process STATE_MEM; + +-- Transition matrix +TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in, spi_busy ) +begin + NEXT_STATE <= SLEEP; + slv_busy_x <= '0'; + slv_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => if ( (spi_busy = '0') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (spi_busy = '0') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + elsif( (spi_busy = '1') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + elsif( (spi_busy = '1') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when RD_RDY => NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + when WR_RDY => NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + when RD_ACK => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + end if; + when WR_ACK => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + end if; + when RD_BSY => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + end if; + when WR_BSY => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + end if; + when DONE => NEXT_STATE <= SLEEP; + + when others => NEXT_STATE <= SLEEP; + end case; +end process TRANSFORM; + +--------------------------------------------------------- +-- data handling -- +--------------------------------------------------------- + +-- register write +THE_WRITE_REG_PROC: process( clk_in, clear_in ) +begin + if( clear_in = '1' ) then + reg_ctrl_data <= (others => '0'); + reg_status_data <= (others => '0'); + spi_start <= '0'; + elsif( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_ctrl_data <= (others => '0'); + reg_status_data <= (others => '0'); + spi_start <= '0'; + elsif( (store_wr = '1') and (slv_addr_in(0) = '0') ) then + reg_ctrl_data <= slv_data_in; + elsif( (store_wr = '1') and (slv_addr_in(0) = '1') ) then + reg_status_data <= slv_data_in; + end if; + spi_start <= spi_start_x; + end if; +end process THE_WRITE_REG_PROC; + +spi_start_x <= '1' when ( (store_wr = '1') and (slv_addr_in(0) = '0') ) else '0'; + +-- register read +THE_READ_REG_PROC: process( clk_in, clear_in ) +begin + if( clear_in = '1' ) then + reg_slv_data_out <= (others => '0'); + elsif( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_slv_data_out <= (others => '0'); + elsif( (store_rd = '1') and (slv_addr_in(0) = '0') ) then + reg_slv_data_out <= reg_ctrl_data; + elsif( (store_rd = '1') and (slv_addr_in(0) = '1') ) then + reg_slv_data_out(31 downto 24) <= reg_status_data(31 downto 24); + reg_slv_data_out(23 downto 16) <= x"00"; + reg_slv_data_out(15 downto 8) <= x"00"; + reg_slv_data_out(7 downto 0) <= spi_bsm; + end if; + end if; +end process THE_READ_REG_PROC; + +-- debug signals +status_data(31 downto 24) <= spi_bsm; +status_data(23) <= spi_start; +status_data(22 downto 0) <= (others => '0'); + +-- output signals +slv_ack_out <= slv_ack; +slv_busy_out <= slv_busy; +slv_data_out <= reg_slv_data_out; +stat <= status_data; + +end Behavioral; diff --git a/special/spi_slim.vhd b/special/spi_slim.vhd new file mode 100755 index 0000000..dcaeda6 --- /dev/null +++ b/special/spi_slim.vhd @@ -0,0 +1,666 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +-- missing: end of PP/RDCMD by data_done signal. + +entity spi_slim is + port( SYSCLK : in std_logic; -- 100MHz sysclock + CLEAR : in std_logic; -- asynchronous reset + RESET : in std_logic; -- synchronous reset + -- Command interface + START_IN : in std_logic; -- one start pulse + BUSY_OUT : out std_logic; -- SPI transactions are ongoing + CMD_IN : in std_logic_vector(7 downto 0); -- SPI command byte + ADL_IN : in std_logic_vector(7 downto 0); -- low address byte + ADM_IN : in std_logic_vector(7 downto 0); -- mid address byte + ADH_IN : in std_logic_vector(7 downto 0); -- high address byte + MAX_IN : in std_logic_vector(7 downto 0); -- number of bytes to write / read (PP/RDCMD) + TXDATA_IN : in std_logic_vector(7 downto 0); -- byte to be transmitted next + TX_RD_OUT : out std_logic; + RXDATA_OUT : out std_logic_vector(7 downto 0); -- current received byte + RX_WR_OUT : out std_logic; + TX_RX_A_OUT : out std_logic_vector(7 downto 0); -- memory block counter for PP/RDCMD + -- SPI interface + SPI_SCK_OUT : out std_logic; + SPI_CS_OUT : out std_logic; + SPI_SDI_IN : in std_logic; + SPI_SDO_OUT : out std_logic; + -- DEBUG + CLK_EN_OUT : out std_logic; + BSM_OUT : out std_logic_vector(7 downto 0); + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); +end spi_slim; + +architecture Behavioral of spi_slim is + +-- new clock divider +signal div_counter : std_logic_vector(1 downto 0); +signal div_done_x : std_logic; +signal div_done : std_logic; -- same as clk_en +signal clk_en : std_logic; -- same as div_done + +-- Statemachine signals +type state_t is (IDLE,CSL,TXCMD,TXADD_H,TXADD_M,TXADD_L,TXDATA,RXDATA, + WAIT1,WAIT2,WAIT3,WAIT4,WAIT5,WAIT6,WAIT7,WAIT8,CSH); +signal STATE, NEXT_STATE : state_t; + +signal rx_ena_x : std_logic; +signal rx_ena : std_logic; +signal tx_ena_x : std_logic; +signal tx_ena : std_logic; +signal busy_x : std_logic; +signal busy : std_logic; +signal spi_cs_x : std_logic; -- SPI chip select (low active) +signal spi_cs : std_logic; +signal spi_sck_x : std_logic; -- SPI clock (rising edge active, from counter) +signal spi_sck : std_logic; +signal tx_load_x : std_logic; -- load TX shift register +signal tx_load : std_logic; +signal tx_done_x : std_logic; -- one memory byte sent +signal tx_done : std_logic; +signal tx_sel_x : std_logic_vector(2 downto 0); -- select TX content +signal tx_sel : std_logic_vector(2 downto 0); +signal rx_store_x : std_logic; -- store RX shift register +signal rx_store : std_logic; +signal rx_complete : std_logic; +signal rst_addr_x : std_logic; -- reset address counter +signal rst_addr : std_logic; + +signal inc_addr_rx_x : std_logic; +signal inc_addr_rx : std_logic; +signal inc_addr_tx_x : std_logic; +signal inc_addr_tx : std_logic; +signal ce_addr_x : std_logic; +signal ce_addr : std_logic; + +signal addr_ctr : std_logic_vector(7 downto 0); +signal data_done_x : std_logic; +signal data_done : std_logic_vector(2 downto 0); + +signal last_tx_bit_x : std_logic; +signal last_tx_bit : std_logic; +signal is_data_x : std_logic; +signal is_data : std_logic; + +-- debug signals +signal bsm_x : std_logic_vector(7 downto 0); +signal debug_x : std_logic_vector(31 downto 0); + +signal start : std_logic; -- buffered start_in signal, as we have a clocked down state machine +signal cmd_int : std_logic_vector(7 downto 0); -- internal command and address bytes +signal adh_int : std_logic_vector(7 downto 0); -- internal command and address bytes +signal adm_int : std_logic_vector(7 downto 0); -- internal command and address bytes +signal adl_int : std_logic_vector(7 downto 0); -- internal command and address bytes +signal max_int : std_logic_vector(7 downto 0); + +-- transmitter +signal tx_sreg : std_logic_vector(7 downto 0); +signal tx_reg_comb : std_logic_vector(7 downto 0); -- multiplexer +signal tx_bit_cnt : std_logic_vector(3 downto 0); + +-- receiver +signal rx_sreg : std_logic_vector(7 downto 0); +signal rx_ready_set : std_logic; +signal rx_bit_cnt_clr : std_logic; +signal rx_bit_cnt : std_logic_vector(3 downto 0); + +signal rd_data : std_logic; +signal rd_data1 : std_logic; +signal rd_data2 : std_logic; + + + +-- registers +signal rx_data : std_logic_vector(7 downto 0); + +-- FLASH commands +-- single byte commands +constant NOP : std_logic_vector(7 downto 0) := x"FF"; -- no cmd to execute +constant WREN : std_logic_vector(7 downto 0) := x"06"; -- write enable -- OK -- CMD +constant WRDI : std_logic_vector(7 downto 0) := x"04"; -- write disable -- OK -- CMD +constant ERASE : std_logic_vector(7 downto 0) := x"C7"; -- chip erase -- OK -- CMD +constant DPD : std_logic_vector(7 downto 0) := x"b9"; -- deep powerdown -- OK -- CMD +constant RDPD : std_logic_vector(7 downto 0) := x"ab"; -- resume powerdown -- OK -- CMD + +constant RDID : std_logic_vector(7 downto 0) := x"9f"; -- read signature -- OK -- CMD + readbyte(n) +constant RDSR : std_logic_vector(7 downto 0) := x"05"; -- read status reg -- OK -- CMD + readbyte(n) + +constant WRSR : std_logic_vector(7 downto 0) := x"01"; -- write stat. reg -- OK -- CMD + writebyte(1) + +constant SE64 : std_logic_vector(7 downto 0) := x"d8"; -- sector erase 64kB -- OK -- CMD + ADH + ADM + ADL +constant SE32 : std_logic_vector(7 downto 0) := x"52"; -- sector erase 32kB -- OK -- CMD + ADH + ADM + ADL +constant SE4 : std_logic_vector(7 downto 0) := x"20"; -- sector erase 32kB -- OK -- CMD + ADH + ADM + ADL +constant SECP : std_logic_vector(7 downto 0) := x"36"; -- sector protect -- OK -- CMD + ADH + ADM + ADL +constant SECU : std_logic_vector(7 downto 0) := x"39"; -- sector unprotect -- OK -- CMD + ADH + ADM + ADL + +constant RDCMD : std_logic_vector(7 downto 0) := x"03"; -- read data -- OK -- CMD + ADH + ADM + ADL + readbyte(n) +constant RDSPR : std_logic_vector(7 downto 0) := x"3c"; -- read sect. prot. -- -- CMD + ADH + ADM + ADL + readbye(n) +constant PP : std_logic_vector(7 downto 0) := x"02"; -- page program -- OK -- CMD + ADH + ADM + ADL + writebyte(n) + + +begin + +----------------------------------------------------------- +-- Debug signals +----------------------------------------------------------- +debug_x(31 downto 24) <= tx_sreg; --(others => '0'); +debug_x(23 downto 20) <= tx_bit_cnt; --(others => '0'); +debug_x(19 downto 16) <= rx_bit_cnt; --(others => '0'); +debug_x(15) <= '0'; +debug_x(14) <= '0'; +debug_x(13) <= inc_addr_tx; +debug_x(12) <= inc_addr_rx; +debug_x(11) <= last_tx_bit; +debug_x(10) <= rx_store; +debug_x(9) <= rst_addr; +debug_x(8) <= rx_ena; +debug_x(7) <= data_done(0); +debug_x(6) <= tx_done; +debug_x(5) <= tx_load; +debug_x(4) <= tx_ena; +debug_x(3) <= is_data; +debug_x(2 downto 0) <= tx_sel; + + +----------------------------------------------------------- +-- +----------------------------------------------------------- + +----------------------------------------------------------- +-- SPI clock generator +----------------------------------------------------------- +THE_CLOCK_DIVIDER: process(clear,sysclk) +begin + if( clear = '1' ) then + div_counter <= (others => '0'); + div_done <= '0'; + spi_sck <= '0'; + elsif( rising_edge(sysclk) ) then + if( reset = '1' ) then + div_counter <= (others => '0'); + div_done <= '0'; + spi_sck <= '0'; + else + div_counter <= div_counter + 1; + div_done <= div_done_x; + spi_sck <= spi_sck_x; + end if; + end if; +end process THE_CLOCK_DIVIDER; + +div_done_x <= '1' when ( div_counter = b"00" ) else '0'; + +spi_sck_x <= '1' when ( ((div_counter = b"11") or (div_counter = b"00")) and + ((tx_ena = '1') or (rx_ena = '1')) ) else '0'; + +clk_en <= div_done; + +----------------------------------------------------------- +-- start signal and local register sets for CMD and ADR +----------------------------------------------------------- +THE_START_PROC: process(clear,sysclk) +begin + if( clear = '1' ) then + start <= '0'; + cmd_int <= (others => '0'); + adh_int <= (others => '0'); + adm_int <= (others => '0'); + adl_int <= (others => '0'); + max_int <= (others => '0'); + elsif( rising_edge(sysclk) ) then + if ( reset = '1' ) then + start <= '0'; + cmd_int <= (others => '0'); + adh_int <= (others => '0'); + adm_int <= (others => '0'); + adl_int <= (others => '0'); + max_int <= (others => '0'); + elsif( (start_in = '1') and (busy = '0') ) then + start <= '1'; + cmd_int <= cmd_in; + adh_int <= adh_in; + adm_int <= adm_in; + adl_int <= adl_in; + max_int <= max_in; + elsif( busy = '1' ) then + start <= '0'; + end if; + end if; +end process THE_START_PROC; + +----------------------------------------------------------- +-- statemachine: clocked process +----------------------------------------------------------- +THE_STATEMACHINE: process( clear, sysclk ) +begin + if( clear = '1' ) then + STATE <= IDLE; + rx_ena <= '0'; + tx_ena <= '0'; + busy <= '0'; + spi_cs <= '1'; + tx_load <= '0'; + tx_sel <= "000"; + rx_store <= '0'; + rst_addr <= '0'; + tx_done <= '0'; + is_data <= '0'; + elsif( rising_edge(sysclk) ) then + if ( reset = '1' ) then + STATE <= IDLE; + rx_ena <= '0'; + tx_ena <= '0'; + busy <= '0'; + spi_cs <= '1'; + tx_load <= '0'; + tx_sel <= "000"; + rx_store <= '0'; + rst_addr <= '0'; + tx_done <= '0'; + is_data <= '0'; + elsif( clk_en = '1' ) then + STATE <= NEXT_STATE; + rx_ena <= rx_ena_x; + tx_ena <= tx_ena_x; + busy <= busy_x; + spi_cs <= spi_cs_x; + tx_load <= tx_load_x; + tx_sel <= tx_sel_x; + rx_store <= rx_store_x; + rst_addr <= rst_addr_x; + tx_done <= tx_done_x; + is_data <= is_data_x; + end if; + end if; +end process THE_STATEMACHINE; + +----------------------------------------------------------- +-- state machine transition table +----------------------------------------------------------- +THE_STATE_TRANSITIONS: process( STATE, cmd_int, start, tx_bit_cnt, rx_bit_cnt, data_done(2) ) +begin + rx_ena_x <= '0'; + tx_ena_x <= '0'; + busy_x <= '1'; + spi_cs_x <= '1'; + tx_load_x <= '0'; + tx_sel_x <= "000"; + rx_store_x <= '0'; + rst_addr_x <= '0'; + tx_done_x <= '0'; + is_data_x <= '0'; + case STATE is + when IDLE => + if( start = '1' ) then + NEXT_STATE <= CSL; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "000"; + rst_addr_x <= '1'; + else + NEXT_STATE <= IDLE; + busy_x <= '0'; + end if; + + when CSL => + NEXT_STATE <= TXCMD; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + + when TXCMD => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXCMD; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when WREN | WRDI | ERASE | DPD | RDPD + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + when SE64 | SE32 | SE4 | PP | RDCMD | SECP | SECU | RDSPR + => NEXT_STATE <= WAIT1; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "001"; -- ADH + when WRSR => NEXT_STATE <= WAIT1; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "100"; -- TXDATA + is_data_x <= '1'; + when RDSR | RDID + => NEXT_STATE <= WAIT1; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "110"; -- "00" + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + end if; + + when WAIT1 => + case cmd_int is + when SE64 | SE32 | SE4 | PP | RDCMD | SECP | SECU | RDSPR + => NEXT_STATE <= TXADD_H; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + when RDSR | RDID + => NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + when WRSR => NEXT_STATE <= TXDATA; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + is_data_x <= '1'; + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when TXADD_H => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXADD_H; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + NEXT_STATE <= WAIT2; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "010"; -- ADM + end if; + + when WAIT2 => + NEXT_STATE <= TXADD_M; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + + when TXADD_M => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXADD_M; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + NEXT_STATE <= WAIT3; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "011"; -- ADL + end if; + + when WAIT3 => + NEXT_STATE <= TXADD_L; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + + when TXADD_L => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXADD_L; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when PP => NEXT_STATE <= WAIT6; + tx_load_x <= '1'; + tx_sel_x <= "100"; -- TXDATA + spi_cs_x <= '0'; + when SE64 | SE32 | SE4 | SECP | SECU + => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + when RDCMD | RDSPR + => NEXT_STATE <= WAIT4; + spi_cs_x <= '0'; + tx_load_x <= '1'; + tx_sel_x <= "110"; -- "00" + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + end if; + + when WAIT4 => + case cmd_int is + when RDCMD | RDSPR + => NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when RXDATA => + if( rx_bit_cnt < x"7" ) then + NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when RDCMD | RDSR | RDID | RDSPR + => NEXT_STATE <= WAIT7; + spi_cs_x <= '0'; + rx_store_x <= '1'; + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + rx_store_x <= '1'; + end case; + end if; + + when WAIT6 => + case cmd_int is + when PP => if( data_done(2) = '1' ) then + NEXT_STATE <= CSH; + spi_cs_x <= '0'; + else + NEXT_STATE <= TXDATA; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + is_data_x <= '1'; + end if; + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when TXDATA => + if( tx_bit_cnt < x"7" ) then + NEXT_STATE <= TXDATA; + tx_ena_x <= '1'; + spi_cs_x <= '0'; + else + case cmd_int is + when PP => NEXT_STATE <= WAIT6; + spi_cs_x <= '0'; + tx_done_x <= '1'; + tx_load_x <= '1'; + tx_sel_x <= "100"; -- TXDATA + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + end if; + is_data_x <= '1'; + + when WAIT7 => + NEXT_STATE <= WAIT8; + spi_cs_x <= '0'; + + when WAIT8 => + case cmd_int is + when RDCMD | RDID | RDSR | RDSPR + => if( data_done(2) = '1' ) then + NEXT_STATE <= CSH; + spi_cs_x <= '0'; + else + NEXT_STATE <= RXDATA; + rx_ena_x <= '1'; + spi_cs_x <= '0'; + end if; + when others => NEXT_STATE <= CSH; + spi_cs_x <= '0'; + end case; + + when WAIT5 => + NEXT_STATE <= CSH; + spi_cs_x <= '0'; + + when CSH => + NEXT_STATE <= IDLE; + busy_x <= '0'; + + end case; +end process THE_STATE_TRANSITIONS; + +-- state machine output table +THE_STATEMACHINE_OUT: process( STATE ) +begin + -- default values + rx_bit_cnt_clr <= '1'; + + case STATE is + when IDLE => bsm_x <= x"00"; + when CSL => bsm_x <= x"09"; + when TXCMD => bsm_x <= x"01"; + when TXDATA => bsm_x <= x"02"; + when TXADD_H => bsm_x <= x"03"; + when TXADD_M => bsm_x <= x"04"; + when TXADD_L => bsm_x <= x"05"; + when RXDATA => bsm_x <= x"07"; + when WAIT1 => bsm_x <= x"10"; + when WAIT2 => bsm_x <= x"11"; + when WAIT3 => bsm_x <= x"12"; + when WAIT4 => bsm_x <= x"13"; + when WAIT8 => bsm_x <= x"17"; + when WAIT6 => bsm_x <= x"15"; + when WAIT5 => bsm_x <= x"14"; + when WAIT7 => bsm_x <= x"16"; + when CSH => bsm_x <= x"08"; + when others => bsm_x <= x"ff"; + end case; +end process THE_STATEMACHINE_OUT; + +-- TX data register multiplexer +THE_TXREG_MUX: process( tx_sel, cmd_int, adh_int, adm_int, adl_int, txdata_in ) +begin + case tx_sel is + when "000" => tx_reg_comb <= cmd_int; + when "001" => tx_reg_comb <= adh_int; + when "010" => tx_reg_comb <= adm_int; + when "011" => tx_reg_comb <= adl_int; + when "100" => tx_reg_comb <= txdata_in; + when "101" => tx_reg_comb <= x"ee"; -- unused + when "110" => tx_reg_comb <= x"00"; -- fixed value + when "111" => tx_reg_comb <= x"ff"; -- fixed value + when others => tx_reg_comb <= x"00"; + end case; +end process THE_TXREG_MUX; + +-- TXData shift register and bit counter +THE_TX_SHIFT_AND_BITCOUNT: process( clear, sysclk ) +begin + if( clear = '1' ) then + tx_sreg <= (others => '0'); + tx_bit_cnt <= (others => '0'); + last_tx_bit <= '0'; + elsif( rising_edge(sysclk) ) then + if ( (clk_en = '1' ) and (tx_load = '1') ) then + tx_bit_cnt <= (others => '0'); + tx_sreg <= tx_reg_comb; + elsif( (clk_en = '1') and (tx_ena = '1') ) then + tx_bit_cnt <= tx_bit_cnt + 1; + tx_sreg <= tx_sreg (6 downto 0) & '0'; + end if; + last_tx_bit <= last_tx_bit_x; + end if; +end process THE_TX_SHIFT_AND_BITCOUNT; + +last_tx_bit_x <= '1' when ( tx_bit_cnt = x"7" ) else '0'; + +-- receiver shift register and bit counter +THE_RX_SHIFT_AND_BITCOUNT: process( clear, sysclk ) +begin + if( clear = '1' ) then + rx_bit_cnt <= (others => '0'); + rx_sreg <= (others => '0'); + elsif( rising_edge(sysclk) ) then + if ( reset = '1' ) then + rx_bit_cnt <= (others => '0'); + rx_sreg <= (others => '0'); + elsif( (clk_en = '1') and (rx_ena = '1') ) then + rx_sreg <= rx_sreg (6 downto 0) & spi_sdi_in; + case rx_bit_cnt is + when x"0" | x"1" | x"2" | x"3" | x"4" | x"5" | x"6" => + rx_bit_cnt <= rx_bit_cnt + 1; + when x"7" => + rx_bit_cnt <= (others => '0'); + when others => + null; + end case; + end if; + end if; +end process THE_RX_SHIFT_AND_BITCOUNT; + +-- the rx_data register +THE_RXDATA_REG: process( clear, sysclk ) +begin + if( clear = '1' ) then + rx_data <= (others => '0'); + rx_complete <= '0'; + elsif( rising_edge(sysclk) ) then + if ( reset = '1' ) then + rx_data <= (others => '0'); + rx_complete <= '0'; + elsif( (clk_en = '1') and (rx_store = '1') ) then + rx_data <= rx_sreg; + rx_complete <= '1'; + else + rx_complete <= '0'; + end if; + end if; +end process; + +-- address generator for external BRAM +THE_ADDR_COUNTER: process( clear, sysclk ) +begin + if( clear = '1' ) then + addr_ctr <= (others => '0'); + data_done <= (others => '0'); + inc_addr_rx <= '0'; + inc_addr_tx <= '0'; + ce_addr <= '0'; + elsif( rising_edge(sysclk) ) then + if ( (reset = '1') or (rst_addr = '1') ) then + addr_ctr <= (others => '0'); + data_done <= (others => '0'); + inc_addr_rx <= '0'; + inc_addr_tx <= '0'; + ce_addr <= '0'; + elsif( ce_addr = '1' ) then + addr_ctr <= addr_ctr + 1; + end if; + data_done(2 downto 1) <= data_done(1 downto 0); + data_done(0) <= data_done_x; + inc_addr_rx <= inc_addr_rx_x; + inc_addr_tx <= inc_addr_tx_x; + ce_addr <= ce_addr_x; + end if; +end process THE_ADDR_COUNTER; + +inc_addr_rx_x <= '1' when ( rx_complete = '1' ) else '0'; +--inc_addr_tx_x <= '1' when ( (clk_en = '1') and (tx_done = '1') ) else '0'; +inc_addr_tx_x <= '1' when ( (clk_en = '1') and (last_tx_bit = '1') and (is_data = '1') ) else '0'; +ce_addr_x <= inc_addr_rx or inc_addr_tx; + +data_done_x <= '1' when ( addr_ctr = max_int ) else '0'; + +-- output signals +spi_cs_out <= spi_cs; +spi_sck_out <= spi_sck; +spi_sdo_out <= tx_sreg(7); +busy_out <= busy; + +tx_rd_out <= '0'; +rxdata_out <= rx_data; +rx_wr_out <= rx_complete; +tx_rx_a_out <= addr_ctr; + +clk_en_out <= clk_en; +bsm_out <= bsm_x; +debug_out <= debug_x; + + +end Behavioral; diff --git a/trb_net16_hub_ipu_logic.vhd b/trb_net16_hub_ipu_logic.vhd index 72fea89..4fc4bcc 100644 --- a/trb_net16_hub_ipu_logic.vhd +++ b/trb_net16_hub_ipu_logic.vhd @@ -111,7 +111,9 @@ architecture trb_net16_hub_ipu_logic_arch of trb_net16_hub_ipu_logic is signal REPLY_MUX_reading : std_logic_vector(POINT_NUMBER-1 downto 0); signal reply_arbiter_result : std_logic_vector(POINT_NUMBER-1 downto 0); - type state_type is (IDLE, WAIT_FOR_REPLY, CHECK_EVENT_INFO, WAIT_FOR_HDR_DATA, GEN_LENGTH, CHECK_DHDR, SENDING_DATA, SENDING_REPLY_TRM, SEND_PADDING, WAITING_FOR_INIT); + type state_type is (IDLE, WAIT_FOR_REPLY, CHECK_EVENT_INFO, WAIT_FOR_HDR_DATA, GEN_LENGTH, + CHECK_DHDR, SENDING_DATA, SENDING_REPLY_TRM, SEND_PADDING, + WAITING_FOR_INIT, WAIT_FOR_END_OF_DHDR, ARBITER_ACTIVE); signal current_state, next_state : state_type; signal packet_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); signal reply_data_counter : unsigned(15 downto 0); @@ -201,6 +203,7 @@ architecture trb_net16_hub_ipu_logic_arch of trb_net16_hub_ipu_logic is signal saved_auto_reading_DHDR : std_logic_vector(POINT_NUMBER-1 downto 0); signal last_REPLY_PACKET_NUM_IN : std_logic_vector(POINT_NUMBER*3-1 downto 0); + signal reply_fsm_statebits : std_logic_vector(3 downto 0); begin @@ -791,7 +794,8 @@ begin ); reply_arbiter_reset <= RESET or not locked; - reply_arbiter_input <= REPLY_DATAREADY_IN and not current_reply_reading_TRM and current_reply_reading_DHDR and not saved_reading_padding; + reply_arbiter_input <= REPLY_DATAREADY_IN and not current_reply_reading_TRM and not saved_reading_padding; + --and current_reply_reading_DHDR -- reply_arbiter_CLK_EN <= not next_point_lock; REPLY_MUX_reading <= reply_arbiter_result; @@ -947,19 +951,18 @@ begin dhdr_addr <= "100"; if reply_compare_finished = '1' then dhdr_addr <= "010"; - next_reply_adder_start <= '1'; next_state <= GEN_LENGTH; end if; when GEN_LENGTH => --now, all HDR are stored, calc sum of HDR lengths + next_reply_adder_start <= '1'; dhdr_addr <= "010"; if enable_packing = '0' or DISABLE_PACKING = 1 then next_reply_adder_final_result <= std_logic_vector(unsigned(reply_adder_result) - number_of_replies + 2); else next_reply_adder_final_result <= std_logic_vector(unsigned(reply_adder_result) - number_of_replies - number_of_replies + 2); end if; - comb_REPLY_POOL_DATAREADY <= '0'; case packet_counter is when c_F2 => @@ -968,29 +971,34 @@ begin when c_F3 => dhdr_addr <= "100"; comb_REPLY_POOL_DATA <= "0000" & evt_seqnr & evt_dtype; - comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; if REPLY_POOL_next_read = '1' then - next_state <= CHECK_DHDR; + comb_REPLY_POOL_DATAREADY <= '1'; + next_state <= WAIT_FOR_END_OF_DHDR; end if; end case; + when WAIT_FOR_END_OF_DHDR => + if or_all(reg_current_reply_auto_reading_DHDR) = '0' then + next_state <= CHECK_DHDR; + end if; + when CHECK_DHDR => comb_REPLY_POOL_DATAREADY <= '0'; case packet_counter is when c_H0 => - comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read and got_all_DHDR; + comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; comb_REPLY_POOL_DATA(2 downto 0) <= TYPE_DAT; comb_REPLY_POOL_DATA(c_DATA_WIDTH-1 downto 3) <= (others => '0'); dhdr_addr <= "100"; - next_reply_compare_start <= REPLY_POOL_next_read and got_all_DHDR; + --next_reply_compare_start <= REPLY_POOL_next_read and got_all_DHDR; when c_F0 => dhdr_addr <= "100"; comb_REPLY_POOL_DATA <= "0001" & evt_dtype & evt_random_code; - if reply_compare_finished = '1' then + --if reply_compare_finished = '1' then next_reply_compare_start <= REPLY_POOL_next_read; comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; dhdr_addr <= "101"; - end if; + --end if; when c_F1 => dhdr_addr <= "101"; comb_REPLY_POOL_DATA <= evt_number; @@ -1013,8 +1021,12 @@ begin when others => --c_F3 comb_REPLY_POOL_DATA <= MY_ADDRESS_IN; comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; - if REPLY_POOL_next_read = '1' then - next_state <= SENDING_DATA; + if REPLY_POOL_next_read = '1' then -- and or_all(reply_arbiter_input) = '1' + if or_all(reply_arbiter_input) = '1' then + next_state <= SENDING_DATA; + else + next_state <= ARBITER_ACTIVE; + end if; reply_arbiter_CLK_EN <= '1'; reply_arbiter_enable <= '1'; dhdr_addr <= "110"; @@ -1022,14 +1034,25 @@ begin end if; end case; + when ARBITER_ACTIVE => + reply_arbiter_CLK_EN <= '1'; + reply_arbiter_enable <= '1'; + + if or_all(reply_arbiter_input) = '1' then + next_state <= SENDING_DATA; + elsif send_reply_trm = '1' then + if packet_counter /= c_H0 then + next_state <= SEND_PADDING; + else + next_state <= SENDING_REPLY_TRM; + end if; + end if; + when SENDING_DATA => reply_arbiter_enable <= '1'; dhdr_addr <= "110"; --length - if packet_counter = c_H0 then --- and not (comb_REPLY_muxed_PACKET_NUM = c_H0 and comb_REPLY_muxed_DATA(2 downto 0) = TYPE_TRM) --- and current_muxed_reading_DAT = '1' then - --sending new H0 without checking for reading_DAT seems to be fine + if packet_counter = c_H0 then --sending new H0 without checking for reading_DAT seems to be fine comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; comb_REPLY_POOL_DATA(2 downto 0) <= TYPE_DAT; comb_REPLY_POOL_DATA(15 downto 3) <= (others => '0'); @@ -1043,10 +1066,10 @@ begin --if number of announced words is reached and F1 or F3 is written, then care about padding if (reply_data_counter = current_point_length and packet_counter(0) = '1' and comb_REPLY_muxed_DATAREADY = '1') or or_all(current_reply_reading_TRM and reply_arbiter_result) = '1' then - reply_arbiter_CLK_EN <= '1'; next_reply_data_counter_reset <= '1'; --either padding or trm follows. So: start reading in any case. start_read_padding <= reply_arbiter_result; + next_state <= ARBITER_ACTIVE; end if; if send_reply_trm = '1' then @@ -1099,11 +1122,27 @@ begin reply_fsm_state(1) <= '1' when current_state = WAIT_FOR_HDR_DATA else '0'; reply_fsm_state(2) <= '1' when current_state = GEN_LENGTH else '0'; reply_fsm_state(3) <= '1' when current_state = CHECK_DHDR else '0'; - reply_fsm_state(4) <= '1' when current_state = SENDING_DATA else '0'; --do not change + reply_fsm_state(4) <= '1' when current_state = SENDING_DATA else '0'; reply_fsm_state(5) <= '1' when current_state = SEND_PADDING else '0'; reply_fsm_state(6) <= '1' when current_state = SENDING_REPLY_TRM else '0'; reply_fsm_state(7) <= '1' when current_state = WAITING_FOR_INIT else '0'; + reply_fsm_statebits <= x"0" when current_state = IDLE else + x"1" when current_state = WAIT_FOR_REPLY else + x"2" when current_state = WAIT_FOR_HDR_DATA else + x"3" when current_state = CHECK_EVENT_INFO else + x"4" when current_state = GEN_LENGTH else + x"5" when current_state = WAIT_FOR_END_OF_DHDR else + x"6" when current_state = CHECK_DHDR else + x"7" when current_state = SENDING_DATA else + x"8" when current_state = ARBITER_ACTIVE else + x"9" when current_state = SEND_PADDING else + x"A" when current_state = SENDING_REPLY_TRM else + x"B" when current_state = WAITING_FOR_INIT else +-- x"C" when current_state = WAIT_FOR_REPLY else +-- x"D" when current_state = WAIT_FOR_REPLY else +-- x"E" when current_state = WAIT_FOR_REPLY else + x"F"; process(CLK) @@ -1185,10 +1224,9 @@ begin STAT_DEBUG(7) <= REPLY_DATA_IN(30); STAT_DEBUG(8) <= got_all_DHDR; --REPLY_DATA_IN(46); STAT_DEBUG(9) <= locked; - STAT_DEBUG(13 downto 10) <= reply_fsm_state(3 downto 0); - STAT_DEBUG(14) <= REPLY_POOL_next_read; - - STAT_DEBUG(15) <= '0'; + STAT_DEBUG(10) <= '0'; + STAT_DEBUG(11) <= REPLY_POOL_next_read; + STAT_DEBUG(15 downto 12) <= reply_fsm_statebits(3 downto 0); STAT_DEBUG(19 downto 16) <= REPLY_DATA_IN(19 downto 16); STAT_DEBUG(20) <= REPLY_DATAREADY_IN(1); diff --git a/trb_net16_regIO.vhd b/trb_net16_regIO.vhd index 4d5f0c0..47ce6fd 100644 --- a/trb_net16_regIO.vhd +++ b/trb_net16_regIO.vhd @@ -1017,11 +1017,11 @@ begin STAT(6 downto 4) <= buf_API_PACKET_NUM_OUT; STAT(7) <= next_API_DATAREADY_OUT; STAT(15 downto 8) <= next_API_DATA_OUT(7 downto 0); - STAT(23 downto 16) <= DAT_ADDR_OUT(7 downto 0); + STAT(23 downto 16) <= x"00";--(7 downto 0); STAT(24) <= DAT_DATAREADY_IN; STAT(25) <= DAT_DATAREADY_IN_before; - STAT(26) <= DAT_READ_ENABLE_OUT; - STAT(27) <= DAT_WRITE_ENABLE_OUT; + STAT(26) <= '0'; --DAT_READ_ENABLE_OUT; + STAT(27) <= '0'; --DAT_WRITE_ENABLE_OUT; STAT(28) <= DAT_NO_MORE_DATA_IN; STAT(29) <= DAT_UNKNOWN_ADDR_IN; STAT(30) <= API_READ_IN; -- 2.43.0