LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cvs-checkins > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: cvs at opencores.org<cvs@o...>
    Date: Sun Mar 25 03:09:54 CEST 2007
    Subject: [cvs-checkins] MODIFIED: simpcon ...
    Top
    Date: 00/07/03 25:03:09

    Added: simpcon/vhdl sc2ahbsl.vhd sc2avalon.vhd sc_cnt.vhd
    sc_fpu.vhd sc_lego.vhd sc_mac.vhd sc_pack.vhd
    sc_sigdel.vhd sc_sram16.vhd sc_sram32_flash.vhd
    sc_uart_tal.vhd sc_usb.vhd sigdel.vhd
    Log:
    update from JOP


    Revision Changes Path
    1.1 simpcon/vhdl/sc2ahbsl.vhd

    http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc2ahbsl.vhd?rev=1.1&content-type=text/x-cvsweb-markup

    Index: sc2ahbsl.vhd
    ===================================================================
    --
    -- sc2ahbsl.vhd
    --
    -- SimpCon to AMBA bridge
    --
    -- Author: Martin Schoeberl martin@j...
    --
    -- 2007-03-16 first version
    --

    Library IEEE;
    use IEEE.std_logic_1164.all;
    use ieee.numeric_std.all;

    use work.jop_types.all;
    use work.sc_pack.all;
    use work.jop_config.all;

    library grlib;
    use grlib.amba.all;
    --use grlib.tech.all;
    library gaisler;
    use gaisler.memctrl.all;
    --use gaisler.pads.all; -- used for I/O pads
    --use gaisler.misc.all;

    entity sc2ahbsl is

    port (

    clk, reset : in std_logic;

    -- SimpCon memory interface
    scmo : in sc_mem_out_type;
    scmi : out sc_in_type;

    -- AMBA slave interface
    ahbsi : out ahb_slv_in_type;
    ahbso : in ahb_slv_out_type
    );
    end sc2ahbsl;

    architecture rtl of sc2ahbsl is

    type state_type is (idl, rd, rdw, wr, wrw);
    signal state : state_type;
    signal next_state : state_type;

    signal reg_wr_data : std_logic_vector(31 downto 0);
    signal reg_rd_data : std_logic_vector(31 downto 0);

    begin

    --
    -- some defaults
    --
    ahbsi.hsel(1 to NAHBSLV-1) <= (others => '0'); -- we use only slave 0
    ahbsi.hsel(0) <= scmo.rd or scmo.wr; -- slave select
    -- do we need to store the addrsss in a register?
    ahbsi.haddr(MEM_ADDR_SIZE-1+2 downto 2) <= scmo.address; -- address bus (byte)
    ahbsi.haddr(1 downto 0) <= (others => '0');
    ahbsi.haddr(31 downto MEM_ADDR_SIZE+2) <= (others => '0');
    ahbsi.hwrite <= scmo.wr; -- read/write
    ahbsi.htrans <= HTRANS_NONSEQ; -- transfer type
    ahbsi.hsize <= "010"; -- transfer size 32 bits
    ahbsi.hburst <= HBURST_SINGLE; -- burst type
    ahbsi.hwdata <= reg_wr_data; -- write data bus
    ahbsi.hprot <= "0000"; -- ? protection control
    ahbsi.hready <= '1'; -- ? transer done
    ahbsi.hmaster <= "0000"; -- current master
    ahbsi.hmastlock <= '0'; -- locked access
    ahbsi.hmbsel(0) <= '0'; -- memory bank select
    ahbsi.hmbsel(1) <= '1'; -- second is SRAM
    ahbsi.hmbsel(2 to NAHBAMR-1) <= (others => '0');
    ahbsi.hcache <= '1'; -- cacheable
    ahbsi.hirq <= (others => '0'); -- interrupt result bus




    --
    -- Register write data
    --
    process(clk, reset)
    begin
    if reset='1' then reg_wr_data <= (others => '0'); elsif rising_edge(clk) then if scmo.wr='1' then reg_wr_data <= scmo.wr_data; end if; end if; end process; -- -- next state logic -- process(state, scmo, ahbso.hready) begin next_state <= state; case state is when idl => if scmo.rd='1' then next_state <= rdw; elsif scmo.wr='1' then next_state <= wrw; end if; when rdw => if ahbso.hready='1' then next_state <= rd; end if; when rd => next_state <= idl; if scmo.rd='1' then next_state <= rdw; elsif scmo.wr='1' then next_state <= wrw; end if; when wrw => if ahbso.hready='1' then next_state <= wr; end if; when wr => next_state <= idl; if scmo.rd='1' then next_state <= rdw; elsif scmo.wr='1' then next_state <= wrw; end if; end case; end process; -- -- state machine register -- and output register -- process(clk, reset) begin if (reset='1') then state <= idl; reg_rd_data <= (others => '0'); elsif rising_edge(clk) then state <= next_state; case next_state is when idl => when rdw => when rd => reg_rd_data <= ahbso.hrdata; when wrw => when wr => end case; end if; end process; -- -- combinatorial state machine output -- process(next_state) begin scmi.rdy_cnt <= "00"; scmi.rd_data <= reg_rd_data; case next_state is when idl => when rdw => scmi.rdy_cnt <= "11"; when rd => scmi.rd_data <= ahbso.hrdata; when wrw => scmi.rdy_cnt <= "11"; when wr => end case; end process; end rtl; 1.1 simpcon/vhdl/sc2avalon.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc2avalon.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc2avalon.vhd =================================================================== -- -- sc2avalon.vhd -- -- SimpCon to Avalon bridge -- -- Author: Martin Schoeberl martin@j... -- -- 2006-08-10 first version -- Library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; entity sc2avalon is generic (addr_bits : integer); port ( clk, reset : in std_logic; -- SimpCon interface sc_address : in std_logic_vector(addr_bits-1 downto 0); sc_wr_data : in std_logic_vector(31 downto 0); sc_rd, sc_wr : in std_logic; sc_rd_data : out std_logic_vector(31 downto 0); sc_rdy_cnt : out unsigned(1 downto 0); -- Avalon interface av_address : out std_logic_vector(addr_bits-1+2 downto 0); av_writedata : out std_logic_vector(31 downto 0); av_byteenable : out std_logic_vector(3 downto 0); av_readdata : in std_logic_vector(31 downto 0); av_read : out std_logic; av_write : out std_logic; av_waitrequest : in std_logic ); end sc2avalon; architecture rtl of sc2avalon is type state_type is (idl, rd, rdw, wr, wrw); signal state : state_type; signal next_state : state_type; signal reg_addr : std_logic_vector(addr_bits-1 downto 0); signal reg_wr_data : std_logic_vector(31 downto 0); signal reg_rd_data : std_logic_vector(31 downto 0); signal reg_rd : std_logic; signal reg_wr : std_logic; begin av_byteenable <= "1111"; -- we use only 32 bit transfers av_address(1 downto 0) <= "00"; sc_rd_data <= reg_rd_data; -- -- Register memory address, write data and read data -- process(clk, reset) begin if reset='1' then reg_addr <= (others => '0'); reg_wr_data <= (others => '0'); elsif rising_edge(clk) then if sc_rd='1' or sc_wr='1' then reg_addr <= sc_address; end if; if sc_wr='1' then reg_wr_data <= sc_wr_data; end if; end if; end process; -- -- The address MUX slightly violates the Avalon -- specification. The address changes from the sc_address -- to the registerd address in the second cycle. However, -- as both registers contain the same value there should be -- no real glitch. For synchronous peripherals this is not -- an issue. For asynchronous peripherals (SRAM) the possible -- glitch should be short enough to be not seen on the output -- pins. -- process(sc_rd, sc_wr, sc_address, reg_addr) begin if sc_rd='1' or sc_wr='1' then av_address(addr_bits-1+2 downto 2) <= sc_address; else av_address(addr_bits-1+2 downto 2) <= reg_addr; end if; end process; -- Same game for the write data and write/read control process(sc_wr, sc_wr_data, reg_wr_data) begin if sc_wr='1' then av_writedata <= sc_wr_data; else av_writedata <= reg_wr_data; end if; end process; av_write <= sc_wr or reg_wr; av_read <= sc_rd or reg_rd; -- -- next state logic -- -- At the moment we do not support back to back read -- or write. We don't need it for JOP, right? -- If needed just copy the idl code to rd and wr. -- process(state, sc_rd, sc_wr, av_waitrequest) begin next_state <= state; case state is when idl => if sc_rd='1' then if av_waitrequest='0' then next_state <= rd; else next_state <= rdw; end if; elsif sc_wr='1' then if av_waitrequest='0' then next_state <= wr; else next_state <= wrw; end if; end if; when rdw => if av_waitrequest='0' then next_state <= rd; end if; when rd => next_state <= idl; when wrw => if av_waitrequest='0' then next_state <= wr; end if; when wr => next_state <= idl; end case; end process; -- -- state machine register -- and output register -- process(clk, reset) begin if (reset='1') then state <= idl; reg_rd_data <= (others => '0'); sc_rdy_cnt <= "00"; reg_rd <= '0'; reg_wr <= '0'; elsif rising_edge(clk) then state <= next_state; sc_rdy_cnt <= "00"; reg_rd <= '0'; reg_wr <= '0'; case next_state is when idl => when rdw => sc_rdy_cnt <= "11"; reg_rd <= '1'; when rd => reg_rd_data <= av_readdata; when wrw => sc_rdy_cnt <= "11"; reg_wr <= '1'; when wr => end case; end if; end process; end rtl; 1.1 simpcon/vhdl/sc_cnt.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_cnt.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_cnt.vhd =================================================================== -- -- sc_cnt.vhd -- -- counter, interrrupt handling and watchdog bit -- -- Author: Martin Schoeberl martin@g... -- -- address map: -- -- 0 read clk counter, write irq ena -- 1 read 1 MHz counter, write timer val (us) + irq ack -- 2 write generates sw-int (for yield()) -- 3 write wd port -- 4 write generates SW exception, read exception reason -- -- todo: -- -- -- 2003-07-05 new IO standard -- 2003-08-15 us counter, irq added -- 2005-11-30 change interface to SimpCon -- 2006-01-11 added exception -- 2007-03-17 changed interrupts to records -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.jop_types.all; entity sc_cnt is generic (addr_bits : integer; clk_freq : integer); port ( clk : in std_logic; reset : in std_logic; -- SimpCon interface address : in std_logic_vector(addr_bits-1 downto 0); wr_data : in std_logic_vector(31 downto 0); rd, wr : in std_logic; rd_data : out std_logic_vector(31 downto 0); rdy_cnt : out unsigned(1 downto 0); -- -- Interrupts from IO devices -- irq_in : out irq_in_type; exc_req : in exception_type; wd : out std_logic ); end sc_cnt ; architecture rtl of sc_cnt is signal clock_cnt : std_logic_vector(31 downto 0); signal pre_scale : std_logic_vector(7 downto 0); signal us_cnt : std_logic_vector(31 downto 0); constant div_val : integer := clk_freq/1000000-1; signal timer_int : std_logic; signal yield_int : std_logic; signal int_ack : std_logic; signal timer : std_logic; signal yield : std_logic; signal irq_cnt : std_logic_vector(31 downto 0); signal timer_equ : std_logic; signal timer_dly : std_logic; signal exc_type : std_logic_vector(7 downto 0); begin rdy_cnt <= "00"; -- no wait states -- -- read cnt values -- process(clk, reset) begin if (reset='1') then rd_data <= (others => '0'); elsif rising_edge(clk) then if rd='1' then case address(2 downto 0) is when "000" => rd_data <= clock_cnt; when "001" => rd_data <= us_cnt; when others => rd_data(7 downto 0) <= exc_type; rd_data(31 downto 8) <= (others => '0'); end case; end if; end if; end process; -- -- compare timer value and us counter -- and generate single shot -- process(us_cnt, irq_cnt) begin timer_equ <= '0'; if us_cnt = irq_cnt then timer_equ <= '1'; end if; end process; process(clk, reset, timer_equ) begin if (reset='1') then timer_dly <= '0'; elsif rising_edge(clk) then timer_dly <= timer_equ; end if; end process; timer_int <= timer_equ and not timer_dly; -- -- int processing from timer and yield request -- process(clk, reset, timer_int, yield_int) begin if (reset='1') then timer <= '0'; yield <= '0'; elsif rising_edge(clk) then if int_ack='1' then timer <= '0'; yield <= '0'; else if timer_int='1' then timer <= '1'; end if; if yield_int='1' then yield <= '1'; end if; end if; end if; end process; irq_in.irq <= timer or yield; -- -- counters -- pre_scale is 8 bit => fmax = 255 MHz -- process(clk, reset) begin if (reset='1') then clock_cnt <= (others => '0'); us_cnt <= (others => '0'); pre_scale <= std_logic_vector(to_unsigned(div_val, pre_scale'length)); elsif rising_edge(clk) then clock_cnt <= std_logic_vector(unsigned(clock_cnt) + 1); pre_scale <= std_logic_vector(unsigned(pre_scale) - 1); if pre_scale = "00000000" then pre_scale <= std_logic_vector(to_unsigned(div_val, pre_scale'length)); us_cnt <= std_logic_vector(unsigned(us_cnt) + 1); end if; end if; end process; -- -- io write processing and exception processing -- process(clk, reset) begin if (reset='1') then irq_in.irq_ena <= '0'; irq_cnt <= (others => '0'); int_ack <= '0'; wd <= '0'; exc_type <= (others => '0'); irq_in.exc_int <= '0'; elsif rising_edge(clk) then int_ack <= '0'; yield_int <= '0'; irq_in.exc_int <= '0'; if exc_req.spov='1' then exc_type(0) <= '1'; irq_in.exc_int <= '1'; end if; if wr='1' then case address(2 downto 0) is when "000" => irq_in.irq_ena <= wr_data(0); when "001" => irq_cnt <= wr_data; int_ack <= '1'; when "010" => yield_int <= '1'; when "011" => wd <= wr_data(0); when others => exc_type <= wr_data(7 downto 0); irq_in.exc_int <= '1'; end case; end if; end if; end process; end rtl; 1.1 simpcon/vhdl/sc_fpu.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_fpu.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_fpu.vhd =================================================================== -- This is the SimpCon interface to the FPU -- Library IEEE; use IEEE.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; entity sc_fpu is generic (ADDR_WIDTH : integer); port ( clk_i : in std_logic; reset_i : in std_logic; -- SimpCon interface address_i : in std_logic_vector(ADDR_WIDTH-1 downto 0); wr_data_i : in std_logic_vector(31 downto 0); rd_i, wr_i : in std_logic; rd_data_o : out std_logic_vector(31 downto 0); rdy_cnt_o : out unsigned(1 downto 0) ); end sc_fpu; architecture rtl of sc_fpu is component fpu port ( clk_i : in std_logic; opa_i : in std_logic_vector(31 downto 0); opb_i : in std_logic_vector(31 downto 0); fpu_op_i : in std_logic_vector(2 downto 0); rmode_i : in std_logic_vector(1 downto 0); output_o : out std_logic_vector(31 downto 0); ine_o : out std_logic; overflow_o : out std_logic; underflow_o : out std_logic; div_zero_o : out std_logic; inf_o : out std_logic; zero_o : out std_logic; qnan_o : out std_logic; snan_o : out std_logic; start_i : in std_logic; ready_o : out std_logic ); end component; signal opa_i, opb_i : std_logic_vector(31 downto 0); signal fpu_op_i : std_logic_vector(2 downto 0); signal rmode_i : std_logic_vector(1 downto 0); signal output_o : std_logic_vector(31 downto 0); signal start_i, ready_o : std_logic ; --signal ine_o, overflow_o, underflow_o, div_zero_o, inf_o, zero_o, qnan_o, snan_o: std_logic; begin -- instantiate the fpu i_fpu: fpu port map ( clk_i => clk_i, opa_i => opa_i, opb_i => opb_i, fpu_op_i => fpu_op_i, rmode_i => rmode_i, output_o => output_o, ine_o => open, overflow_o => open, underflow_o => open, div_zero_o => open, inf_o => open, zero_o => open, qnan_o => open, snan_o => open, start_i => start_i, ready_o => ready_o); rmode_i <= "00"; -- default rounding mode= round-to-nearest-even -- master reads from FPU process(clk_i, reset_i) begin if (reset_i='1') then start_i <= '0'; elsif rising_edge(clk_i) then if rd_i='1' then -- that's our very simple address decoder if address_i="0011" then start_i <= '1'; end if; else start_i <= '0'; end if; end if; end process; -- set rdy_cnt process(clk_i) begin if (reset_i='1') then rdy_cnt_o <= "11"; elsif rising_edge(clk_i) then if start_i='1' then rdy_cnt_o <= "11"; elsif ready_o = '1' then rdy_cnt_o <= "00"; rd_data_o <= output_o; end if; end if; end process; -- master writes to FPU process(clk_i, reset_i) begin if (reset_i='1') then opa_i <= (others => '0'); opb_i <= (others => '0'); fpu_op_i <= (others => '0'); elsif rising_edge(clk_i) then if wr_i='1' then if address_i="0000" then opa_i <= wr_data_i; elsif address_i="0001" then opb_i <= wr_data_i; elsif address_i="0010" then fpu_op_i <=wr_data_i(2 downto 0); end if; end if; end if; end process; end rtl; 1.1 simpcon/vhdl/sc_lego.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_lego.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_lego.vhd =================================================================== -- -- sc_lego.vhd -- -- Motor and sensor interface for LEGO MindStorms -- -- Author: Martin Schoeberl martin@j... -- -- address map: -- -- 0 motor output, sensor input -- 1 not used -- 2 not used -- 3 not used -- -- 2005-12-22 adapted for SimpCon interface -- -- todo: -- -- -- -- lesens -- -- sigma delta AD converter and power switch -- for the LEGO sensor. -- -- TODO: write a general sigma delta ADC -- But this one is special as the senso gets powered! -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity lesens is generic (clk_freq : integer); port ( clk : in std_logic; reset : in std_logic; dout : out std_logic_vector(8 downto 0); sp : out std_logic; sdi : in std_logic; sdo : out std_logic ); end lesens ; architecture rtl of lesens is signal clkint : unsigned(8 downto 0); -- 9 bit ADC signal val : unsigned(8 downto 0); signal rx_d : std_logic; signal serdata : std_logic; signal spike : std_logic_vector(2 downto 0); -- sync in, filter signal pow_cnt : unsigned(2 downto 0); signal clksd : std_logic; signal prescale : unsigned(7 downto 0); constant sd_clk_cnt : integer := ((clk_freq+1000000)/2000000)-1; begin -- -- power switch for sensor -- process(pow_cnt) begin sp <= '1'; if pow_cnt=0 or pow_cnt=1 then sp <= '0'; end if; end process; sdo <= serdata; -- -- prescaler (2 MHz clock) -- process(clk, reset) begin if (reset='1') then prescale <= (others => '0'); clksd <= '0'; elsif rising_edge(clk) then clksd <= '0'; prescale <= prescale + 1; if prescale = sd_clk_cnt then prescale <= (others => '0'); clksd <= '1'; end if; end if; end process; -- -- sigma delta converter -- process(clk, reset) begin if (reset='1') then spike <= "000"; dout <= (others => '0'); val <= (others => '0'); clkint <= (others => '0'); serdata <= '0'; pow_cnt <= (others => '0'); elsif rising_edge(clk) then if clksd='1' then -- -- delay -- spike(0) <= sdi; spike(2 downto 1) <= spike(1 downto 0); serdata <= rx_d; -- no inverter, using an invert. comperator -- -- integrate -- if serdata='0' then -- 'invert' value val <= val+1; end if; if clkint=0 then -- 256 us if pow_cnt=1 then dout <= std_logic_vector(val); end if; val <= (others => '0'); pow_cnt <= pow_cnt + 1; end if; clkint <= clkint+1; -- free running counter end if; end if; end process; -- -- filter input -- with spike select rx_d <= '0' when "000", '0' when "001", '0' when "010", '1' when "011", '0' when "100", '1' when "101", '1' when "110", '1' when "111", 'X' when others; end rtl; -- -- lego io -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity sc_lego is generic (addr_bits : integer; clk_freq : integer); port ( clk : in std_logic; reset : in std_logic; -- SimpCon interface address : in std_logic_vector(addr_bits-1 downto 0); wr_data : in std_logic_vector(31 downto 0); rd, wr : in std_logic; rd_data : out std_logic_vector(31 downto 0); rdy_cnt : out unsigned(1 downto 0); -- motor stuff ma_en : out std_logic; ma_l1 : out std_logic; ma_l2 : out std_logic; ma_l1_sdi : in std_logic; ma_l1_sdo : out std_logic; ma_l2_sdi : in std_logic; ma_l2_sdo : out std_logic; mb_en : out std_logic; mb_l1 : out std_logic; mb_l2 : out std_logic; -- sensor stuff s1_pow : out std_logic; s1_sdi : in std_logic; s1_sdo : out std_logic ); end sc_lego; architecture rtl of sc_lego is signal m_out : std_logic_vector(5 downto 0); signal sensor : std_logic_vector(8 downto 0); signal xyz : std_logic_vector(31 downto 0); begin rdy_cnt <= "00"; -- no wait states -- -- The registered MUX is all we need for a SimpCon read. -- The read data is stored in registered rd_data. -- process(clk, reset) begin if (reset='1') then rd_data <= (others => '0'); elsif rising_edge(clk) then if rd='1' then -- that's our very simple address decoder if address(0)='0' then rd_data(8 downto 0) <= sensor; rd_data(31 downto 9) <= (others => '0'); else rd_data <= xyz; end if; end if; end if; end process; -- -- SimpCon write is very simple -- process(clk, reset) begin if (reset='1') then xyz <= (others => '0'); m_out <= (others => '0'); elsif rising_edge(clk) then if wr='1' then xyz <= wr_data; m_out <= wr_data(5 downto 0); end if; end if; end process; -- simple motor out mb_en <= m_out(5); mb_l1 <= m_out(4); mb_l2 <= m_out(3); ma_en <= m_out(2); ma_l1 <= m_out(1); ma_l2 <= m_out(0); ma_l1_sdo <= '0'; ma_l2_sdo <= '0'; -- sensor adc cmp_sens: entity work.lesens generic map ( clk_freq => clk_freq ) port map( clk => clk, reset => reset, dout => sensor, sp => s1_pow, sdi => s1_sdi, sdo => s1_sdo ); end rtl; 1.1 simpcon/vhdl/sc_mac.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_mac.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_mac.vhd =================================================================== -- -- sc_mac.vhd -- -- A simple MAC unit with a SimpCon interface -- -- Author: Martin Schoeberl martin@j... -- -- -- resources on Cyclone -- -- xx LCs, max xx MHz -- -- -- 2006-02-12 first version -- -- todo: -- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; LIBRARY lpm; USE lpm.lpm_components.all; entity mac is port ( clk : in std_logic; reset : in std_logic; -- SimpCon interface opa, opb : in std_logic_vector(31 downto 0); start : in std_logic; clear : in std_logic; result : out std_logic_vector(63 downto 0) ); end mac; architecture rtl of mac is SIGNAL sub_wire0 : STD_LOGIC_VECTOR (63 DOWNTO 0); COMPONENT lpm_mult GENERIC ( lpm_hint : STRING; lpm_pipeline : NATURAL; lpm_representation : STRING; lpm_type : STRING; lpm_widtha : NATURAL; lpm_widthb : NATURAL; lpm_widthp : NATURAL; lpm_widths : NATURAL ); PORT ( dataa : IN STD_LOGIC_VECTOR (31 DOWNTO 0); datab : IN STD_LOGIC_VECTOR (31 DOWNTO 0); clock : IN STD_LOGIC ; result : OUT STD_LOGIC_VECTOR (63 DOWNTO 0) ); END COMPONENT; type state_type is (idle, mul, add); signal state : state_type; signal cnt : unsigned(5 downto 0); signal mul_res : unsigned(63 downto 0); signal acc : unsigned(63 downto 0); begin lpm_mult_component : lpm_mult GENERIC MAP ( lpm_hint => "MAXIMIZE_SPEED=5", lpm_pipeline => 16, lpm_representation => "SIGNED", lpm_type => "LPM_MULT", lpm_widtha => 32, lpm_widthb => 32, lpm_widthp => 64, lpm_widths => 1 ) PORT MAP ( dataa => opa, datab => opb, clock => clk, result => sub_wire0 ); mul_res <= unsigned(sub_wire0); process(clk, reset) begin if reset='1' then acc <= (others => '0'); elsif rising_edge(clk) then case state is when idle => if start='1' then state <= mul; cnt <= "010010"; -- for shure end if; when mul => cnt <= cnt-1; if cnt=0 then state <= add; end if; when add => acc <= acc + mul_res; state <= idle; end case; if clear='1' then acc <= (others => '0'); end if; end if; result <= std_logic_vector(acc); end process; end rtl; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity sc_mac is generic (addr_bits : integer; scale : integer := 16); port ( clk : in std_logic; reset : in std_logic; -- SimpCon interface address : in std_logic_vector(addr_bits-1 downto 0); wr_data : in std_logic_vector(31 downto 0); rd, wr : in std_logic; rd_data : out std_logic_vector(31 downto 0); rdy_cnt : out unsigned(1 downto 0) ); end sc_mac; architecture rtl of sc_mac is signal opa, opb : std_logic_vector(31 downto 0); signal result : std_logic_vector(63 downto 0); signal start : std_logic; signal clear : std_logic; begin rdy_cnt <= "00"; -- no wait states, we are hopefully fast enough cm: entity work.mac port map( clk => clk, reset => reset, opa => opa, opb => opb, start => start, clear => clear, result => result ); -- -- SimpCon read and write -- process(clk, reset) begin if reset='1' then rd_data <= (others => '0'); elsif rising_edge(clk) then start <= '0'; if wr='1' then if address(0)='0' then opa <= wr_data; else opb <= wr_data; start <= '1'; end if; end if; -- get MAC result scaled by 'scale' and clear the accumulator clear <= '0'; if rd='1' then -- if address(0)='0' then rd_data <= result(31+scale downto scale); clear <= '1'; -- else -- rd_data <= result(63 downto 32); -- end if; end if; end if; end process; end rtl; 1.1 simpcon/vhdl/sc_pack.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_pack.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_pack.vhd =================================================================== -- -- sc_pack.vhd -- -- Package for SimpCon defines -- -- Author: Martin Schoeberl (martin@j...) -- -- -- 2007-03-16 first version -- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package sc_pack is constant MEM_ADDR_SIZE : integer := 21; constant IO_ADDR_SIZE : integer := 7; constant RDY_CNT_SIZE : integer := 2; type sc_mem_out_type is record address : std_logic_vector(MEM_ADDR_SIZE-1 downto 0); wr_data : std_logic_vector(31 downto 0); rd : std_logic; wr : std_logic; end record; type sc_io_out_type is record address : std_logic_vector(IO_ADDR_SIZE-1 downto 0); wr_data : std_logic_vector(31 downto 0); rd : std_logic; wr : std_logic; end record; type sc_in_type is record rd_data : std_logic_vector(31 downto 0); rdy_cnt : unsigned(RDY_CNT_SIZE-1 downto 0); end record; end sc_pack; 1.1 simpcon/vhdl/sc_sigdel.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_sigdel.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_sigdel.vhd =================================================================== -- -- sc_sigdel.vhd -- -- A simple sigma-delta ADC and PWM DAC for the SimpCon interface -- -- Author: Martin Schoeberl martin@j... -- -- -- resources on Cyclone -- -- xx LCs, max xx MHz -- -- -- 2006-04-16 first version -- -- todo: -- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.jop_config.all; entity sc_sigdel is generic (addr_bits : integer; fsamp : integer); port ( clk : in std_logic; reset : in std_logic; -- SimpCon interface address : in std_logic_vector(addr_bits-1 downto 0); wr_data : in std_logic_vector(31 downto 0); rd, wr : in std_logic; rd_data : out std_logic_vector(31 downto 0); rdy_cnt : out unsigned(1 downto 0); -- io ports sdi : in std_logic; -- input of the sigma-delta ADC sdo : out std_logic; -- output of the sigma-delta ADC dac : out std_logic -- output of the PWM DAC ); end sc_sigdel; architecture rtl of sc_sigdel is -- we use a 10MHz sigma-delta clock constant SDF : integer := 10000000; constant SDTICK : integer := (clk_freq+SDF/2)/SDF; signal clksd : integer range 0 to SDTICK; constant CNT_MAX : integer := (SDF+fsamp/2)/fsamp; signal cnt : integer range 0 to CNT_MAX; signal dac_cnt : integer range 0 to CNT_MAX; signal rx_d : std_logic; signal serdata : std_logic; signal spike : std_logic_vector(2 downto 0); -- sync in, filter signal sum : unsigned(15 downto 0); signal delta : unsigned(15 downto 0); signal audio_in : std_logic_vector(15 downto 0); signal audio_out : std_logic_vector(15 downto 0); signal sample_rdy : std_logic; signal sample_rd : std_logic; signal sample_wr : std_logic; begin rdy_cnt <= "00"; -- no wait states -- we use only 16 bits -- bit 31 is the ready bit rd_data(30 downto 16) <= (others => '0'); -- -- The registered MUX is all we need for a SimpCon read. -- The read data is stored in registered rd_data. -- process(clk, reset) begin if (reset='1') then rd_data(15 downto 0) <= (others => '0'); rd_data(31) <= '0'; sample_rd <= '0'; elsif rising_edge(clk) then sample_rd <= '0'; if rd='1' then rd_data(15 downto 0) <= audio_in; rd_data(31) <= sample_rdy; sample_rd <= '1'; end if; end if; end process; -- -- SimpCon write is very simple -- process(clk, reset) begin if (reset='1') then audio_out <= (others => '0'); sample_wr <= '0'; elsif rising_edge(clk) then sample_wr <= '0'; if wr='1' then audio_out <= wr_data(15 downto 0); sample_wr <= '1'; end if; end if; end process; -- -- Here we go with the simple sigma-delta converter: -- process(clk, reset) begin if reset='1' then spike <= "000"; clksd <= 0; cnt <= 0; sum <= (others => '0'); sample_rdy <= '0'; elsif rising_edge(clk) then if clksd=0 then clksd <= SDTICK-1; spike(0) <= sdi; spike(2 downto 1) <= spike(1 downto 0); sdo <= not rx_d; serdata <= rx_d; if cnt=0 then cnt <= CNT_MAX-1; audio_in <= std_logic_vector(sum); sample_rdy <= '1'; sum <= (others => '0'); -- BTW: we miss one sigma-delta sample here... else cnt <= cnt-1; if serdata='1' then sum <= sum+1; end if; end if; else clksd <= clksd-1; end if; -- reset ready flag after read if sample_rd='1' then sample_rdy <= '0'; end if; end if; end process; -- -- filter input (majority voting) -- with spike select rx_d <= '0' when "000", '0' when "001", '0' when "010", '1' when "011", '0' when "100", '1' when "101", '1' when "110", '1' when "111", 'X' when others; -- -- and here comes the primitive version of the -- digital delta part - not really delta... -- it's just a simple PWM... -- now do it with the main clock... -- process(clk, reset) begin if reset='1' then delta <= (others => '0'); dac <= '0'; dac_cnt <= 0; elsif rising_edge(clk) then if dac_cnt=0 then dac_cnt <= CNT_MAX-1; delta <= unsigned(audio_out); else dac_cnt <= dac_cnt-1; dac <= '0'; if delta /= 0 then delta <= delta-1; dac <= '1'; end if; end if; end if; end process; end rtl; 1.1 simpcon/vhdl/sc_sram16.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_sram16.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_sram16.vhd =================================================================== -- -- sc_sram16.vhd -- -- SimpCon compliant external memory interface -- for 16-bit SRAM (e.g. Altera DE2 board) -- -- High 16-bit word is at lower address -- -- Connection between mem_sc and the external memory bus -- -- memory mapping -- -- 000000-x7ffff external SRAM (w mirror) max. 512 kW (4*4 MBit) -- -- RAM: 16 bit word -- -- -- 2006-08-01 Adapted from sc_ram32.vhd -- 2006-08-16 Rebuilding the already working (lost) version -- Use wait_state, din register without MUX -- Library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; use work.jop_types.all; entity sc_mem_if is generic (ram_ws : integer; addr_bits : integer); port ( clk, reset : in std_logic; -- SimpCon interface address : in std_logic_vector(addr_bits-1 downto 0); wr_data : in std_logic_vector(31 downto 0); rd, wr : in std_logic; rd_data : out std_logic_vector(31 downto 0); rdy_cnt : out unsigned(1 downto 0); -- memory interface ram_addr : out std_logic_vector(addr_bits-1 downto 0); ram_dout : out std_logic_vector(15 downto 0); ram_din : in std_logic_vector(15 downto 0); ram_dout_en : out std_logic; ram_ncs : out std_logic; ram_noe : out std_logic; ram_nwe : out std_logic ); end sc_mem_if; architecture rtl of sc_mem_if is -- -- signals for mem interface -- type state_type is ( idl, rd1_h, rd2_h, rd1_l, rd2_l, wr_h, wr_idl, wr_l ); signal state : state_type; signal next_state : state_type; signal nwr_int : std_logic; signal wait_state : unsigned(3 downto 0); signal cnt : unsigned(1 downto 0); signal dout_ena : std_logic; signal rd_data_ena_h : std_logic; signal rd_data_ena_l : std_logic; signal inc_addr : std_logic; signal wr_low : std_logic; signal ram_dout_low : std_logic_vector(15 downto 0); signal ram_din_low : std_logic_vector(15 downto 0); signal ram_din_reg : std_logic_vector(31 downto 0); begin ram_dout_en <= dout_ena; rdy_cnt <= cnt; -- -- Register memory address, write data and read data -- process(clk, reset) begin if reset='1' then ram_addr <= (others => '0'); ram_dout <= (others => '0'); ram_dout_low <= (others => '0'); elsif rising_edge(clk) then if rd='1' or wr='1' then ram_addr <= address(addr_bits-2 downto 0) & "0"; end if; if inc_addr='1' then ram_addr(0) <= '1'; end if; if wr='1' then ram_dout <= wr_data(31 downto 16); ram_dout_low <= wr_data(15 downto 0); end if; if wr_low='1' then ram_dout <= ram_dout_low; end if; if rd_data_ena_h='1' then ram_din_reg(15 downto 0) <= ram_din; end if; if rd_data_ena_l='1' then -- move first word to higher half ram_din_reg(31 downto 16) <= ram_din_reg(15 downto 0); -- read second word ram_din_reg(15 downto 0) <= ram_din; end if; end if; end process; rd_data <= ram_din_reg; -- -- 'delay' nwe 1/2 cycle -> change on falling edge -- process(clk, reset) begin if (reset='1') then ram_nwe <= '1'; elsif falling_edge(clk) then ram_nwe <= nwr_int; end if; end process; -- -- next state logic -- process(state, rd, wr, wait_state) begin next_state <= state; case state is when idl => if rd='1' then if ram_ws=0 then -- then we omit state rd1! next_state <= rd2_h; else next_state <= rd1_h; end if; elsif wr='1' then next_state <= wr_h; end if; -- the WS state when rd1_h => if wait_state=2 then next_state <= rd2_h; end if; when rd2_h => -- go to read low word if ram_ws=0 then -- then we omit state rd1! next_state <= rd2_l; else next_state <= rd1_l; end if; -- the WS state when rd1_l => if wait_state=2 then next_state <= rd2_l; end if; -- last read state when rd2_l => next_state <= idl; -- This should do to give us a pipeline -- level of 2 for read if rd='1' then if ram_ws=0 then -- then we omit state rd1! next_state <= rd2_h; else next_state <= rd1_h; end if; elsif wr='1' then next_state <= wr_h; end if; -- the WS state when wr_h => -- TODO: check what happens on ram_ws=0 -- TODO: do we need a write pipelining? -- not at the moment, but parhaps later when -- we write the stack content to main memory if wait_state=1 then next_state <= wr_idl; end if; -- one idle state for nwr to go high when wr_idl => next_state <= wr_l; -- the WS state when wr_l => if wait_state=1 then next_state <= idl; end if; end case; end process; -- -- state machine register -- output register -- process(clk, reset) begin if (reset='1') then state <= idl; dout_ena <= '0'; ram_ncs <= '1'; ram_noe <= '1'; rd_data_ena_h <= '0'; rd_data_ena_l <= '0'; inc_addr <= '0'; wr_low <= '0'; elsif rising_edge(clk) then state <= next_state; dout_ena <= '0'; ram_ncs <= '1'; ram_noe <= '1'; rd_data_ena_h <= '0'; rd_data_ena_l <= '0'; inc_addr <= '0'; wr_low <= '0'; case next_state is when idl => -- the wait state when rd1_h => ram_ncs <= '0'; ram_noe <= '0'; -- high word last read state when rd2_h => ram_ncs <= '0'; ram_noe <= '0'; rd_data_ena_h <= '1'; inc_addr <= '1'; -- the wait state when rd1_l => ram_ncs <= '0'; ram_noe <= '0'; -- low word last read state when rd2_l => ram_ncs <= '0'; ram_noe <= '0'; rd_data_ena_l <= '1'; -- the WS state when wr_h => ram_ncs <= '0'; dout_ena <= '1'; -- high word last write state when wr_idl => ram_ncs <= '1'; dout_ena <= '1'; inc_addr <= '1'; wr_low <= '1'; -- the WS state when wr_l => ram_ncs <= '0'; dout_ena <= '1'; end case; end if; end process; -- -- nwr combinatorial processing -- for the negativ edge -- process(next_state, state) begin nwr_int <= '1'; -- this is the 'correct' version wich needs -- at minimum 2 cycles for the RAM access -- if (state=wr_l and next_state=wr_l) or -- (state=wr_h and next_state=wr_h) then -- Slightly out of the SRAM spec. nwr goes -- low befor ncs to allow single cycle -- access if next_state=wr_l or next_state=wr_h then nwr_int <= '0'; end if; end process; -- -- wait_state processing -- process(clk, reset) begin if (reset='1') then wait_state <= (others => '1'); cnt <= "00"; elsif rising_edge(clk) then wait_state <= wait_state-1; cnt <= "11"; if next_state=idl then cnt <= "00"; end if; if rd='1' or wr='1' then wait_state <= to_unsigned(ram_ws+1, 4); end if; if state=rd2_h or state=wr_idl then wait_state <= to_unsigned(ram_ws+1, 4); if ram_ws<3 then cnt <= to_unsigned(ram_ws+1, 2); else cnt <= "11"; end if; end if; if state=rd1_l or state=rd2_l or state=wr_l then -- take care for pipelined cach transfer -- there is no idl state and cnt should -- go back to "11" if rd='0' and wr='0' then -- if wait_state<4 then if wait_state(3 downto 2)="00" then cnt <= wait_state(1 downto 0)-1; end if; end if; end if; end if; end process; end rtl; 1.1 simpcon/vhdl/sc_sram32_flash.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_sram32_flash.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_sram32_flash.vhd =================================================================== -- -- sc_sram32_flash.vhd -- -- SimpCon compliant external memory interface -- for 32-bit SRAM (e.g. Cyclone board) -- -- Connection between mem_sc and the external memory bus -- -- memory mapping -- -- 0x000000-x7ffff external SRAM (w mirror) max. 512 kW (4*4 MBit) -- 0x080000-xfffff external Flash (w mirror) max. 512 kB (4 MBit) -- 0x100000-xfffff external NAND flash -- -- RAM: 32 bit word -- ROM: 8 bit word (for flash programming) -- -- todo: -- -- -- 2005-11-22 first version -- 2005-12-02 added flash interface -- Library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; use work.jop_types.all; use work.sc_pack.all; entity sc_mem_if is generic (ram_ws : integer; rom_ws : integer); port ( clk, reset : in std_logic; -- -- SimpCon memory interface -- sc_mem_out : in sc_mem_out_type; sc_mem_in : out sc_in_type; -- memory interface ram_addr : out std_logic_vector(17 downto 0); ram_dout : out std_logic_vector(31 downto 0); ram_din : in std_logic_vector(31 downto 0); ram_dout_en : out std_logic; ram_ncs : out std_logic; ram_noe : out std_logic; ram_nwe : out std_logic; -- -- config/program flash and big nand flash interface -- fl_a : out std_logic_vector(18 downto 0); fl_d : inout std_logic_vector(7 downto 0); fl_ncs : out std_logic; fl_ncsb : out std_logic; fl_noe : out std_logic; fl_nwe : out std_logic; fl_rdy : in std_logic ); end sc_mem_if; architecture rtl of sc_mem_if is -- -- signals for mem interface -- type state_type is ( idl, rd1, rd2, wr1, fl_rd1, fl_rd2, fl_wr1, fl_wr2 ); signal state : state_type; signal next_state : state_type; signal nwr_int : std_logic; signal wait_state : unsigned(3 downto 0); signal cnt : unsigned(1 downto 0); signal dout_ena : std_logic; signal ram_data : std_logic_vector(31 downto 0); signal ram_data_ena : std_logic; signal flash_dout : std_logic_vector(7 downto 0); signal fl_dout_ena : std_logic; signal flash_data : std_logic_vector(7 downto 0); signal flash_data_ena : std_logic; signal nand_rdy : std_logic; signal trans_ram : std_logic; signal trans_flash : std_logic; -- selection for read mux signal ram_access : std_logic; -- selection for Flash/NAND ncs signal sel_flash : std_logic; begin assert MEM_ADDR_SIZE>=21 report "Too less address bits"; ram_dout_en <= dout_ena; sc_mem_in.rdy_cnt <= cnt; -- -- decode ram/flash -- The signals are only valid for the first cycle -- process(sc_mem_out.address(20 downto 19)) begin trans_ram <= '0'; trans_flash <= '0'; case sc_mem_out.address(20 downto 19) is when "00" => trans_ram <= '1'; when "01" => trans_flash <= '1'; when others => null; end case; end process; -- -- Register memory address, write data and read data -- process(clk, reset) begin if reset='1' then ram_addr <= (others => '0'); ram_dout <= (others => '0'); ram_data <= (others => '0'); flash_dout <= (others => '0'); fl_a <= (others => '0'); sel_flash <= '1'; -- AMD default ram_access <= '1'; -- RAM default elsif rising_edge(clk) then if sc_mem_out.rd='1' or sc_mem_out.wr='1' then if trans_ram='1' then ram_access <= '1'; ram_addr <= sc_mem_out.address(17 downto 0); else ram_access <= '0'; fl_a <= sc_mem_out.address(18 downto 0); -- select flash type -- and keep it selected if trans_flash='1' then sel_flash <= '1'; else sel_flash <= '0'; end if; end if; end if; if sc_mem_out.wr='1' then if trans_ram='1' then ram_dout <= sc_mem_out.wr_data; else flash_dout <= sc_mem_out.wr_data(7 downto 0); end if; end if; if ram_data_ena='1' then ram_data <= ram_din; end if; if flash_data_ena='1' then -- signal NAND rdy only for NAND access nand_rdy <= fl_rdy and not sel_flash; flash_data <= fl_d; end if; end if; end process; -- -- MUX registered RAM and Flash data -- process(ram_access, ram_data, flash_data, nand_rdy) begin if (ram_access='1') then sc_mem_in.rd_data <= ram_data; else sc_mem_in.rd_data <= std_logic_vector(to_unsigned(0, 32-9)) & nand_rdy & flash_data; end if; end process; -- -- 'delay' nwe 1/2 cycle -> change on falling edge -- process(clk, reset) begin if (reset='1') then ram_nwe <= '1'; elsif falling_edge(clk) then ram_nwe <= nwr_int; end if; end process; -- -- next state logic -- process(state, sc_mem_out.rd, sc_mem_out.wr, trans_ram, wait_state) begin next_state <= state; case state is when idl => if sc_mem_out.rd='1' then if trans_ram='1' then if ram_ws=0 then -- then we omit state rd1! next_state <= rd2; else next_state <= rd1; end if; else next_state <= fl_rd1; end if; elsif sc_mem_out.wr='1' then if trans_ram='1' then next_state <= wr1; else next_state <= fl_wr1; end if; end if; -- the WS state when rd1 => if wait_state=2 then next_state <= rd2; end if; -- last read state when rd2 => next_state <= idl; -- This should do to give us a pipeline -- level of 2 for read -- we don't care about a flash trans. -- in the pipeline! if sc_mem_out.rd='1' then if ram_ws=0 then -- then we omit state rd1! next_state <= rd2; else next_state <= rd1; end if; elsif sc_mem_out.wr='1' then next_state <= wr1; end if; -- the WS state when wr1 => -- TODO: check what happens on ram_ws=0 -- TODO: do we need a write pipelining? -- not at the moment, but parhaps later when -- we write the stack content to main memory if wait_state=1 then next_state <= idl; end if; when fl_rd1 => if wait_state=2 then next_state <= fl_rd2; end if; when fl_rd2 => next_state <= idl; -- we do no pipelining with the Flashs when fl_wr1 => if wait_state=2 then next_state <= fl_wr2; end if; when fl_wr2 => next_state <= idl; end case; end process; -- -- state machine register -- output register (RAM, Flash control lines) -- process(clk, reset) begin if (reset='1') then state <= idl; dout_ena <= '0'; ram_ncs <= '1'; ram_noe <= '1'; ram_data_ena <= '0'; fl_noe <= '1'; fl_nwe <= '1'; flash_data_ena <= '0'; fl_dout_ena <= '0'; elsif rising_edge(clk) then state <= next_state; dout_ena <= '0'; ram_ncs <= '1'; ram_noe <= '1'; ram_data_ena <= '0'; fl_noe <= '1'; fl_nwe <= '1'; flash_data_ena <= '0'; fl_dout_ena <= '0'; case next_state is when idl => -- the wait state when rd1 => ram_ncs <= '0'; ram_noe <= '0'; -- last read state when rd2 => ram_ncs <= '0'; ram_noe <= '0'; ram_data_ena <= '1'; -- the WS state when wr1 => ram_ncs <= '0'; dout_ena <= '1'; when fl_rd1 => fl_noe <= '0'; when fl_rd2 => fl_noe <= '0'; flash_data_ena <= '1'; when fl_wr1 => fl_nwe <= '0'; fl_dout_ena <= '1'; when fl_wr2 => fl_dout_ena <= '1'; end case; end if; end process; -- -- nwr combinatorial processing -- for the negativ edge -- process(next_state, state) begin nwr_int <= '1'; if next_state=wr1 then nwr_int <= '0'; end if; end process; -- -- wait_state processing -- cs delay, dout enable -- process(clk, reset) begin if (reset='1') then wait_state <= (others => '1'); cnt <= "00"; elsif rising_edge(clk) then wait_state <= wait_state-1; cnt <= "11"; if next_state=idl then cnt <= "00"; -- if wait_state<4 then elsif wait_state(3 downto 2)="00" then cnt <= wait_state(1 downto 0)-1; end if; if sc_mem_out.rd='1' or sc_mem_out.wr='1' then if trans_ram='1' then wait_state <= to_unsigned(ram_ws+1, 4); if ram_ws<3 then cnt <= to_unsigned(ram_ws+1, 2); else cnt <= "11"; end if; else wait_state <= to_unsigned(rom_ws+1, 4); cnt <= "11"; end if; end if; end if; end process; -- -- Flash signals -- -- -- leave last ncs. Only toggle between two flashs. -- fl_ncs <= not sel_flash; -- Flash ncs fl_ncsb <= sel_flash; -- NAND ncs -- -- tristate output -- process(fl_dout_ena, flash_dout) begin if (fl_dout_ena='1') then fl_d <= flash_dout(7 downto 0); else fl_d <= (others => 'Z'); end if; end process; end rtl; 1.1 simpcon/vhdl/sc_uart_tal.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_uart_tal.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_uart_tal.vhd =================================================================== -- -- sc_uart_tal.vhd -- -- 8-N-1 serial interface -- conf_reg: baud_rate and 2400, HW hs on/off, DTR -- default: 101 => baud_rate, no HW hs, DTR on -- -- wr, rd should be one cycle long => trde, rdrf goes 0 one cycle later -- -- Author: Martin Schoeberl martin@j... -- -- -- resources on ACEX1K30-3 -- -- 100 LCs, max 90 MHz -- -- resetting rts with fifo_full-1 works with C program on pc -- but not with javax.comm: sends some more bytes after deassert -- of rts (16 byte blocks regardless of rts). -- Try to stop with half full fifo. -- -- todo: -- -- -- 2000-12-02 first working version -- 2002-01-06 changed tdr and rdr to fifos. -- 2002-05-15 changed clkdiv calculation -- 2002-11-01 don't wait if read fifo is full, just drop the byte -- 2002-11-03 use threshold in fifo to reset rts -- don't send if cts is '0' -- 2002-11-08 rx fifo to 20 characters and stop after 4 -- 2003-07-05 new IO standard, change cts/rts to neg logic -- 2003-09-19 sync ncts in! -- 2004-03-23 two stop bits -- 2004-04-23 Version for TAL -- 2004-04-26 DTR is inverted conf_reg(0) => '1' means set DTR! -- 2005-02-28 Changed default conf_reg to no hand shake (ignore ncts) -- 2005-12-27 change interface to SimpCon -- 2006-08-13 use 3 FFs for the rxd input at clk -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity sc_uart_tal is generic (addr_bits : integer; clk_freq : integer; baud_rate : integer; txf_depth : integer; txf_thres : integer; rxf_depth : integer; rxf_thres : integer); port ( clk : in std_logic; reset : in std_logic; -- SimpCon interface address : in std_logic_vector(addr_bits-1 downto 0); wr_data : in std_logic_vector(31 downto 0); rd, wr : in std_logic; rd_data : out std_logic_vector(31 downto 0); rdy_cnt : out unsigned(1 downto 0); txd : out std_logic; rxd : in std_logic; ncts : in std_logic; nrts : out std_logic; dtr : out std_logic ); end sc_uart_tal; architecture rtl of sc_uart_tal is component fifo is generic (width : integer; depth : integer; thres : integer); port ( clk : in std_logic; reset : in std_logic; din : in std_logic_vector(width-1 downto 0); dout : out std_logic_vector(width-1 downto 0); rd : in std_logic; wr : in std_logic; empty : out std_logic; full : out std_logic; half : out std_logic ); end component; -- -- signals for uart connection -- signal ua_dout : std_logic_vector(7 downto 0); signal ua_wr, tdre : std_logic; signal ua_rd, rdrf : std_logic; signal conf_reg : std_logic_vector(2 downto 0); type uart_tx_state_type is (s0, s1); signal uart_tx_state : uart_tx_state_type; signal tf_dout : std_logic_vector(7 downto 0); -- fifo out signal tf_rd : std_logic; signal tf_empty : std_logic; signal tf_full : std_logic; signal tf_half : std_logic; signal ncts_buf : std_logic_vector(2 downto 0); -- sync in signal ncts_in : std_logic; signal tsr : std_logic_vector(9 downto 0); -- tx shift register signal tx_clk : std_logic; type uart_rx_state_type is (s0, s1, s2); signal uart_rx_state : uart_rx_state_type; signal rf_wr : std_logic; signal rf_empty : std_logic; signal rf_full : std_logic; signal rf_half : std_logic; signal rxd_reg : std_logic_vector(2 downto 0); signal rx_buf : std_logic_vector(2 downto 0); -- sync in, filter signal rx_d : std_logic; -- rx serial data signal rsr : std_logic_vector(9 downto 0); -- rx shift register signal rx_clk : std_logic; signal rx_clk_ena : std_logic; constant clk16_fast_cnt : integer := (clk_freq/baud_rate+8)/16-1; constant clk16_slow_cnt : integer := (clk_freq/2400+8)/16-1; signal clk16_cnt : integer range 0 to clk16_slow_cnt; begin rdy_cnt <= "00"; -- no wait states rd_data(31 downto 8) <= std_logic_vector(to_unsigned(0, 24)); -- -- The registered MUX is all we need for a SimpCon read. -- The read data is stored in registered rd_data. -- process(clk, reset) begin if (reset='1') then rd_data(7 downto 0) <= (others => '0'); elsif rising_edge(clk) then ua_rd <= '0'; if rd='1' then -- that's our very simple address decoder if address(0)='0' then rd_data(7 downto 0) <= "000000" & rdrf & tdre; else rd_data(7 downto 0) <= ua_dout; ua_rd <= rd; end if; end if; end if; end process; -- write is on address offest 1 ua_wr <= wr and address(0); -- -- SimpCon write is very simple -- process(clk, reset) begin if (reset='1') then conf_reg <= "101"; elsif rising_edge(clk) then -- config register is at offset 0 if wr='1' and address(0)='0' then conf_reg <= wr_data(2 downto 0); end if; if conf_reg(2)='1' then clk16_cnt <= clk16_fast_cnt; else clk16_cnt <= clk16_slow_cnt; end if; end if; end process; dtr <= not conf_reg(0); -- -- serial clock -- process(clk, reset) variable clk16 : integer range 0 to clk16_slow_cnt; variable clktx : unsigned(3 downto 0); variable clkrx : unsigned(3 downto 0); begin if (reset='1') then clk16 := 0; clktx := "0000"; clkrx := "0000"; tx_clk <= '0'; rx_clk <= '0'; rx_buf <= "111"; elsif rising_edge(clk) then rxd_reg(0) <= rxd; -- to avoid setup timing error in Quartus rxd_reg(1) <= rxd_reg(0); rxd_reg(2) <= rxd_reg(1); if (clk16=clk16_cnt) then -- 16 x serial clock clk16 := 0; -- -- tx clock -- clktx := clktx + 1; if (clktx="0000") then tx_clk <= '1'; else tx_clk <= '0'; end if; -- -- rx clock -- if (rx_clk_ena='1') then clkrx := clkrx + 1; if (clkrx="1000") then rx_clk <= '1'; else rx_clk <= '0'; end if; else clkrx := "0000"; end if; -- -- sync in filter buffer -- rx_buf(0) <= rxd_reg(2); rx_buf(2 downto 1) <= rx_buf(1 downto 0); else clk16 := clk16 + 1; tx_clk <= '0'; rx_clk <= '0'; end if; end if; end process; -- -- transmit fifo -- cmp_tf: fifo generic map (8, txf_depth, txf_thres) port map (clk, reset, wr_data(7 downto 0), tf_dout, tf_rd, ua_wr, tf_empty, tf_full, tf_half); -- -- state machine for actual shift out -- process(clk, reset) variable i : integer range 0 to 11; begin if (reset='1') then uart_tx_state <= s0; tsr <= "1111111111"; tf_rd <= '0'; ncts_buf <= "111"; ncts_in <= '1'; elsif rising_edge(clk) then ncts_buf(0) <= ncts; ncts_buf(2 downto 1) <= ncts_buf(1 downto 0); if conf_reg(1)='1' then ncts_in <= ncts_buf(2); else ncts_in <= '0'; end if; case uart_tx_state is when s0 => i := 0; if (tf_empty='0' and ncts_in='0') then uart_tx_state <= s1; tsr <= tf_dout & '0' & '1'; tf_rd <= '1'; end if; when s1 => tf_rd <= '0'; if (tx_clk='1') then tsr(9) <= '1'; tsr(8 downto 0) <= tsr(9 downto 1); i := i+1; if (i=11) then -- two stop bits uart_tx_state <= s0; end if; end if; end case; end if; end process; txd <= tsr(0); tdre <= not tf_full; -- -- receive fifo -- cmp_rf: fifo generic map (8, rxf_depth, rxf_thres) port map (clk, reset, rsr(8 downto 1), ua_dout, ua_rd, rf_wr, rf_empty, rf_full, rf_half); rdrf <= not rf_empty; nrts <= rf_half; -- glitches even on empty fifo! -- -- filter rxd -- with rx_buf select rx_d <= '0' when "000", '0' when "001", '0' when "010", '1' when "011", '0' when "100", '1' when "101", '1' when "110", '1' when "111", 'X' when others; -- -- state machine for actual shift in -- process(clk, reset) variable i : integer range 0 to 10; begin if (reset='1') then uart_rx_state <= s0; rsr <= "0000000000"; rf_wr <= '0'; rx_clk_ena <= '0'; elsif rising_edge(clk) then case uart_rx_state is when s0 => i := 0; rf_wr <= '0'; if (rx_d='0') then rx_clk_ena <= '1'; uart_rx_state <= s1; else rx_clk_ena <= '0'; end if; when s1 => if (rx_clk='1') then rsr(9) <= rx_d; rsr(8 downto 0) <= rsr(9 downto 1); i := i+1; if (i=10) then uart_rx_state <= s2; end if; end if; when s2 => rx_clk_ena <= '0'; if rsr(0)='0' and rsr(9)='1' then if rf_full='0' then -- if full just drop it rf_wr <= '1'; end if; end if; uart_rx_state <= s0; end case; end if; end process; end rtl; 1.1 simpcon/vhdl/sc_usb.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sc_usb.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sc_usb.vhd =================================================================== -- -- sc_usb.vhd -- -- Interface to FTDI FT2232C parallel port B -- -- Author: Martin Schoeberl martin@j... -- -- -- resources on Cyclone -- -- xx LCs, max xx MHz -- -- -- 2005-08-23 first version -- -- todo: -- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.jop_types.all; entity sc_usb is generic (addr_bits : integer; clk_freq : integer); port ( clk : in std_logic; reset : in std_logic; -- SimpCon interface address : in std_logic_vector(addr_bits-1 downto 0); wr_data : in std_logic_vector(31 downto 0); rd, wr : in std_logic; rd_data : out std_logic_vector(31 downto 0); rdy_cnt : out unsigned(1 downto 0); -- FTDI 2232 connection data : inout std_logic_vector(7 downto 0); nrxf : in std_logic; ntxe : in std_logic; nrd : out std_logic; ft_wr : out std_logic; nsi : out std_logic ); end sc_usb; architecture rtl of sc_usb is signal usb_out : std_logic_vector(7 downto 0); signal usb_in : std_logic_vector(7 downto 0); signal read_ack : std_logic; signal fifo_wr : std_logic; -- -- constant WS : integer := (clk_freq/20000000)+1; signal cnt : integer range 0 to WS; -- -- FIFO signals -- signal tf_dout : std_logic_vector(7 downto 0); -- fifo out signal tf_rd : std_logic; signal tf_empty : std_logic; signal tf_full : std_logic; signal rf_din : std_logic_vector(7 downto 0); -- fifo input signal rf_wr : std_logic; signal rf_empty : std_logic; signal rf_full : std_logic; -- -- USB interface signals -- type state_type is (idle, inact, rx1, rx2, tx1, tx2); signal state : state_type; signal usb_dout : std_logic_vector(7 downto 0); signal usb_din : std_logic_vector(7 downto 0); signal nrxf_buf : std_logic_vector(1 downto 0); signal ntxe_buf : std_logic_vector(1 downto 0); signal rdr, wrr : std_logic_vector(7 downto 0); signal data_oe : std_logic; begin rdy_cnt <= "00"; -- no wait states rd_data(31 downto 8) <= std_logic_vector(to_unsigned(0, 24)); -- -- The registered MUX is all we need for a SimpCon read. -- The read data is stored in registered rd_data. -- process(clk, reset) begin if (reset='1') then rd_data(7 downto 0) <= (others => '0'); elsif rising_edge(clk) then read_ack <= '0'; if rd='1' then -- that's our very simple address decoder if address(0)='0' then rd_data(7 downto 0) <= "000000" & not rf_empty & not tf_full; else rd_data(7 downto 0) <= usb_dout; read_ack <= rd; end if; end if; end if; end process; -- write is on address offest 1 fifo_wr <= wr and address(0); -- we don't use the send immediate nsi <= '1'; -- -- receive fifo -- rxfifo: entity work.fifo generic map ( width => 8, depth => 4, thres => 2 -- we don't care about the half signal ) port map ( clk => clk, reset => reset, din => rf_din, dout => usb_dout, rd => read_ack, wr => rf_wr, empty => rf_empty, full => rf_full, half => open ); -- -- transmit fifo -- txfifo: entity work.fifo generic map ( width => 8, depth => 4, thres => 2 -- we don't care about the half signal ) port map ( clk => clk, reset => reset, din => wr_data(7 downto 0), dout => tf_dout, rd => tf_rd, wr => fifo_wr, empty => tf_empty, full => tf_full, half => open ); -- -- state machine for the usb bus -- process(clk, reset) begin if (reset='1') then state <= idle; nrxf_buf <= "11"; ntxe_buf <= "11"; cnt <= WS; rdr <= (others => '0'); wrr <= (others => '0'); tf_rd <= '0'; rf_wr <= '0'; nrd <= '1'; ft_wr <= '0'; elsif rising_edge(clk) then -- input register nrxf_buf(0) <= nrxf; nrxf_buf(1) <= nrxf_buf(0); ntxe_buf(0) <= ntxe; ntxe_buf(1) <= ntxe_buf(0); case state is when idle => cnt <= WS; tf_rd <= '0'; rf_wr <= '0'; nrd <= '1'; ft_wr <= '0'; data_oe <= '0'; if rf_full='0' and nrxf_buf(1)='0' then nrd <= '0'; state <= rx1; elsif tf_empty='0' and ntxe_buf(1)='0' then ft_wr <= '1'; wrr <= tf_dout; tf_rd <= '1'; state <= tx1; end if; when inact => tf_rd <= '0'; rf_wr <= '0'; nrd <= '1'; ft_wr <= '0'; data_oe <= '0'; cnt <= cnt-1; if cnt=0 then state <= idle; end if; when rx1 => cnt <= cnt-1; if cnt=0 then state <= rx2; rdr <= data; end if; when rx2 => nrd <= '1'; rf_wr <= '1'; cnt <= WS; state <= inact; when tx1 => tf_rd <= '0'; data_oe <= '1'; cnt <= cnt-1; if cnt=0 then state <= tx2; ft_wr <= '0'; end if; when tx2 => data_oe <= '0'; cnt <= WS; state <= inact; end case; end if; end process; data <= wrr when data_oe='1' else (others => 'Z'); rf_din <= data; end rtl; 1.1 simpcon/vhdl/sigdel.vhd http://www.opencores.org/cvsweb.shtml/simpcon/vhdl/sigdel.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: sigdel.vhd =================================================================== -- -- sigdel.vhd -- -- sigma delta AD converter -- -- without external comperator: -- input threshhold of Acex is used as comperator -- (not very exact but only 3 external components) -- -- -- 100k -- ___ -- sdo o--|___|--+ -- | -- 100k | -- ___ | -- uin o--|___|--o----------o sdi -- | -- --- -- --- 100n -- | -- | -- --- -- - -- -- -- Author: Martin Schoeberl martin@j... -- -- -- resources on ACEX1K30-3 -- -- xx LCs, max xx MHz -- -- -- todo: -- use clk_freq, make it configurable -- use a 'real' LP -- -- -- 2002-02-23 first working version -- 2002-08-08 free running 16 bit counter -> 16 bit ADC -- 2003-09-23 new IO standard -- 2005-12-28 just a simple data port -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity sigdel is generic (clk_freq : integer); port ( clk : in std_logic; reset : in std_logic; dout : out std_logic_vector(15 downto 0); sdi : in std_logic; sdo : out std_logic ); end sigdel ; architecture rtl of sigdel is signal clksd : unsigned(4 downto 0); signal clkint : unsigned(15 downto 0); signal val : unsigned(15 downto 0); signal sd_dout : std_logic_vector(15 downto 0); signal rx_d : std_logic; signal serdata : std_logic; signal spike : std_logic_vector(2 downto 0); -- sync in, filter begin sdo <= serdata; dout <= sd_dout; -- -- sigma delta converter -- process(clk, reset) begin if (reset='1') then clksd <= "00000"; spike <= "000"; sd_dout <= (others => '0'); val <= (others => '0'); clkint <= (others => '0'); serdata <= '0'; elsif rising_edge(clk) then clksd <= clksd+1; if clksd="00000" then -- with 20 MHz => 625 kHz -- -- delay -- spike(0) <= sdi; spike(2 downto 1) <= spike(1 downto 0); serdata <= rx_d; -- no inverter, using an invert. comperator -- serdata <= not rx_d; -- without comperator -- -- integrate -- if serdata='0' then -- 'invert' value val <= val+1; end if; if clkint=0 then -- some time... (9.5 Hz) sd_dout <= std_logic_vector(val); val <= (others => '0'); end if; clkint <= clkint+1; -- free running counter end if; end if; end process; -- -- filter input -- with spike select rx_d <= '0' when "000", '0' when "001", '0' when "010", '1' when "011", '0' when "100", '1' when "101", '1' when "110", '1' when "111", 'X' when others; end rtl;

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.