LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; ----------------------------------------------- --dcsboard srg design full version 4 -- -->supports 9 ports write, one port read -->software switchable hamming -->security timeout from 0 to 6.5 sec --21.06.2006 Jens Steckert ----------------------------------------------- --Entity ----------------------------------------------- entity scomm4 is --connections to the outside world port ( --input writedata : in std_logic_vector(31 downto 0); clk : in std_logic; rst_n : in std_logic; write_n : in std_logic; --write control, takes data only when negative... --controlled by avalon bus... read_n : in std_logic; --read control signal from the avalon bus address : in std_logic_vector(3 downto 0);--receives adress for mux -- instr : in std_logic; -- input strobe indata : in std_logic; -- input serial data readdata : out std_logic_vector(31 downto 0); --received data --output -- SERIAL_OUT : out std_logic;--serial output (1 channel) SERIAL_OUT : out std_logic_vector(8 downto 0); --9 output channels STROBE : out std_logic ; --common strobe clkout : out std_logic --common serial clock ); end scomm4; -------------------------------------------------------------- --Architecture -------------------------------------------------------------- architecture a of scomm4 is --shiftregister parin serial out component shreg_parin is generic(N : Integer := 24); port( rst_n : in std_logic; PARIN : in std_logic_vector(N downto 1); CLK : in std_logic; --VALID : in std_logic; SDOUT : out std_logic; SSTR : out std_logic; sclk : out std_logic ); end component; --shift register with serial in / parallel out component shreg is generic(N : Integer := 24); port( rst_n : in std_logic; SCLK : in std_logic; SDIN : in std_logic; SSTR : in std_logic; SDOUT : out std_logic; PAROUT : out std_logic_vector(N downto 1) ); end component; --timeout component timeout is port( --clock input clk_in : in std_logic; refresh : in std_logic; timeval : in std_logic_vector(15 downto 0); --clock output expired : out std_logic ); end component; --hamming encoder component hamming_enc_dmem is port ( din : in std_logic_vector (31 downto 0); -- data from the device dout : out std_logic_vector (38 downto 0) -- data to instr. memory ); end component; --hamming decoder component hamming_dec_dmem is port ( din : in std_logic_vector (38 downto 0); -- data from data memory dout : out std_logic_vector (31 downto 0); -- data to CPU state : out std_logic_vector ( 1 downto 0) ); end component; --clock divider component fdiv is port( rst_n : in std_logic; clk_in : in std_logic; clk_out : out std_logic ); end component; --global clock buffer for the 10kHz main clock signal component global is port(a_in : in std_logic; a_out : out std_logic ); end component; ----------------------- --signal definitions... ----------------------- signal serout : std_logic_vector(8 downto 0);--serial data for 1 ch signal CLK_i10k : std_logic:= '0'; --internal clock, not amplified signal clk_i10kg : std_logic:= '0'; --internal clock, after global buffer signal clk_i10kg_n : std_logic ; -- amplified to drive whole design signal strobe_i : std_logic_vector(8 downto 0); --common strobe signal reset_i : std_logic; --internal reset signal expired_i :std_logic; --interal timer expired, flushes registers --with zero signal settime_i :std_logic; --sets the new time value signal refresh_i :std_logic; --refreshs the timer signal timebuffer : std_logic_vector(15 downto 0); --the time value signal writebuffer : std_logic_vector(31 downto 0);--contains clear text data signal writeoutbuffer : std_logic_vector(38 downto 0); --contains hamming encoded data signal muxbuffer: std_logic_vector(38 downto 0); --contains the data to send signal stor : std_logic_vector(2 downto 0); --dummy storage register signal readbuffer : std_logic_vector(38 downto 0); --buffers data from serial input register signal decreadbuffer :std_logic_vector(31 downto 0); --buffers data from input hamming decoder signal readmuxbuffer : std_logic_vector(31 downto 0); signal sinputbuffer : std_logic; --buffers serial bits at input signal addressbuffer : std_logic_vector(3 downto 0); --buffers the address signal optionregister :std_logic_vector(31 downto 0); --buffers the option string CONSTANT refresh : std_logic_vector(3 DOWNTO 0) := "0000"; CONSTANT ch1 : std_logic_vector(3 DOWNTO 0) := "0001"; CONSTANT ch2 : std_logic_vector(3 DOWNTO 0) := "0010"; CONSTANT ch3 : std_logic_vector(3 DOWNTO 0) := "0011"; CONSTANT ch4 : std_logic_vector(3 DOWNTO 0) := "0100"; CONSTANT ch5 : std_logic_vector(3 DOWNTO 0) := "0101"; CONSTANT ch6 : std_logic_vector(3 DOWNTO 0) := "0110"; CONSTANT ch7 : std_logic_vector(3 DOWNTO 0) := "0111"; CONSTANT ch8 : std_logic_vector(3 DOWNTO 0) := "1000"; CONSTANT ch9 : std_logic_vector(3 DOWNTO 0) := "1001"; CONSTANT settime : std_logic_vector(3 DOWNTO 0) := "1100"; CONSTANT readinput : std_logic_vector(3 DOWNTO 0) := "1101"; CONSTANT option : std_logic_vector(3 DOWNTO 0) := "1110"; CONSTANT changetime : std_logic_vector(3 DOWNTO 0) := "1111"; type data_array is array (0 to 8) of std_logic_vector(38 downto 0); signal wdata_array : data_array; ---------------------------------------------------- --portmapping and connecting the logical blocks ---------------------------------------------------- begin --if bus sets the write_n signal low the data and adress --will be written into the writebuffer register. oproc: process (clk) begin if clk'event and clk ='1' then --rising clock edge if write_n = '0' then case address is when option => optionregister <= writedata; when changetime => timebuffer <= writedata(15 downto 0); when others => writebuffer <= writedata; end case; addressbuffer <= address; --if something (data or config) is written, control programm is --alive. Therefore refresh of timeout is set to 1 refresh_i <= '1'; else --if nothing is written refresh is set to 0 refresh_i <= '0'; end if; if read_n = '0' then --read mux case address is when option => readdata <= optionregister(31 downto 0); WHEN ch1 => readdata <= wdata_array(0)(31 downto 0); WHEN ch2 => readdata <= wdata_array(1)(31 downto 0); WHEN ch3 => readdata <= wdata_array(2)(31 downto 0); WHEN ch4 => readdata <= wdata_array(3)(31 downto 0); WHEN ch5 => readdata <= wdata_array(4)(31 downto 0); WHEN ch6 => readdata <= wdata_array(5)(31 downto 0); WHEN ch7 => readdata <= wdata_array(6)(31 downto 0); WHEN ch8 => readdata <= wdata_array(7)(31 downto 0); WHEN ch9 => readdata <= wdata_array(8)(31 downto 0); WHEN settime => readdata <= x"0000" & timebuffer(15 downto 0); WHEN readinput => readdata <= readmuxbuffer(31 downto 0); when others => readdata <= writedata(31 downto 0); end case; end if; end if; end process; --hamming mux with optionregister(3 downto 0) select muxbuffer <= writeoutbuffer(38 downto 0) when "1111", "0000000" & writebuffer(31 downto 0) when "0000", (others => '0') when others; with optionregister(3 downto 0) select readmuxbuffer <= decreadbuffer(31 downto 0) when "1111", --change this in the next actel version readbuffer(31 downto 0) when "0000", (others => '0') when others; --put those signals out of process... reset_i <= rst_n; clk_i10kg_n <= not clk_i10kg; clkout <= clk_i10kg_n; --inverting clock out to avoid glitches sinputbuffer <= indata; serial_out <= serout; strobe <= strobe_i(1); writemux: PROCESS (addressbuffer, muxbuffer, clk_i10kg) BEGIN -- PROCESS readmux if expired_i = '0' then if clk_i10kg'event and clk_i10kg ='1' then --rising clock edge --w_en <= '0'; CASE addressbuffer IS WHEN ch1 => wdata_array(0) <= muxbuffer; WHEN ch2 => wdata_array(1) <= muxbuffer; WHEN ch3 => wdata_array(2) <= muxbuffer; WHEN ch4 => wdata_array(3) <= muxbuffer; WHEN ch5 => wdata_array(4) <= muxbuffer; WHEN ch6 => wdata_array(5) <= muxbuffer; WHEN ch7 => wdata_array(6) <= muxbuffer; WHEN ch8 => wdata_array(7) <= muxbuffer; WHEN ch9 => wdata_array(8) <= muxbuffer; --dummy command WHEN OTHERS => stor <= muxbuffer(2 downto 0); --<= (OTHERS => '0'); END CASE; end if; else --if timer is expired clear output; for i in 0 to 8 loop wdata_array(i) <= (others => '0'); end loop; end if; END PROCESS writemux; -------------------------------port maps...<------------------- --------------------------------------------------------- --generates 9 shift registers of type shreg_parin --------------------------------------------------------- multishift: for i in 0 to 8 generate mpsreg: shreg_parin generic map(N => 39) port map( rst_n => reset_i, parin => wdata_array(i), clk => clk_i10kg, sstr => strobe_i(i), sdout => serout(i) ); end generate; --serial register pssreg: shreg generic map(n => 39) port map( rst_n => reset_i, SCLK => clk_i10kg_n, SDIN => sinputbuffer, SSTR => strobe_i(1), Parout => readbuffer ); --clock divider fdiv40: fdiv port map( rst_n => reset_i, clk_in =>clk, --fast clock from avalon bus... clk_out => clk_i10k --slow clock for srg ); --hamming encoder hammigenc: hamming_enc_dmem port map( din => writebuffer, dout => writeoutbuffer ); --hamming decoder hammingdec: hamming_dec_dmem port map( din => readbuffer, dout => decreadbuffer ); --timeoutwatchdog watchdog: timeout port map( clk_in => clk_i10kg, refresh => refresh_i, timeval => timebuffer, expired => expired_i ); -------------------------------------------------------------------------------- --!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --for sim purpose only simclk: process(clk_i10k) begin clk_i10kg <= clk_i10k; end process; --glob: global --port map( -- a_in => clk_i10k, -- a_out => clk_i10kg -- ); end;