From athanas@pequod.ee.vt.edu Fri Aug 4 06:19:26 1995 Received: from holodeck.cc.vt.edu (holodeck.cc.vt.edu [128.173.16.28]) by mail.holonet.net with ESMTP id GAA27068; Fri, 4 Aug 1995 06:19:23 -0700 Received: from pequod.ee.vt.edu.ee.vt.edu by holodeck.cc.vt.edu with SMTP (8.6.12/16.2) id JAA15843; Fri, 4 Aug 1995 09:19:22 -0400 Received: by pequod.ee.vt.edu.ee.vt.edu (4.1/Ultrix2.4-C) id AA07613; Fri, 4 Aug 95 09:17:27 EDT Date: Fri, 4 Aug 95 09:17:27 EDT From: athanas@pequod.ee.vt.edu (Peter Athanas) Message-Id: <9508041317.AA07613@pequod.ee.vt.edu.ee.vt.edu> To: gigaops@gigaops.com Subject: yfpga.vhd Status: O --||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--|| --|| Synthesizable model for YFPGA (based on the GO tutorial) --|| 5/95 P.Athanas (Virginia Tech) --|| --|| This model contains the YFPGA shell definition, along --|| with a state machine to facilitate communications with the --|| XFPGA. This facilitates initialization of XFPGA resources. --|| several other features are included (and not so well documented --|| below -- sorry). --|| --|| This model references the hif_444 module, which is the HBUS --|| interface module closely resembling the one described in the --|| GigaOps tutorial (by Brad Taylor). --|| --|| NOTE: This has been checked-out, and seems to work fine; --|| however, if you should notice odd behavior that necessitates --|| repair, please report it to athanas@vt.edu. --|| --||--||--||--||--||--||--||--||--||--||--||--||--||--||--||--|| LIBRARY IEEE; USE ieee.std_logic_1164.all; ENTITY yfpga IS PORT ( hbus_clk : in Std_Logic; hbus_data : inout Std_Logic_Vector(15 downto 0); hbus_func : in Std_Logic_Vector(3 downto 0); hbus_ok : inout Std_Logic; hbus_select : inout Std_Logic; hbus_wrc : in Std_Logic; ybus_dlo : inout Std_Logic_Vector(15 downto 0); ybus_dhi : inout Std_Logic_Vector(15 downto 0); ybus_fun : out Std_Logic_Vector(1 downto 0); ybus_clk : in Std_Logic; ybus_wrc : in Std_Logic; hmem_data : inout Std_Logic_Vector(15 downto 0); hmem_addr : out Std_Logic_Vector(15 downto 0); hmem_se_b : out Std_Logic; hmem_ext_b : out Std_Logic; hmem_ras_b : out Std_Logic; hmem_cas_b : out Std_Logic; hmem_wr_b : out Std_Logic; hmem_rd_b : out Std_Logic; pmem_data : inout Std_Logic_Vector(15 downto 0); pmem_addr : out Std_Logic_Vector(11 downto 2); qmem_ras_b : out Std_Logic; pmem_ras_b : out Std_Logic; qmem_cas_b : out Std_Logic; pmem_wr_b : out Std_Logic; pmem_rd_b : out Std_Logic; pq_func : inout Std_Logic_Vector(10 downto 0); q_stat : inout Std_Logic_Vector(1 downto 0); pq_clk : in Std_Logic; pq_sclk : out Std_Logic; pic_clk : in Std_Logic; hpga_init : in Std_Logic; pic_rgb : in Std_Logic_Vector(2 downto 0); pq_addr_e_b : out Std_Logic; pq_data_e_b : out Std_Logic; xbus0_e_b : out Std_Logic; xbus1_e_b : out Std_Logic; xbus2_e_b : out Std_Logic; xbus3_e_b : out Std_Logic; dbug_tms : in Std_Logic; dbug_hdc : in Std_Logic; dbug_ldc : in Std_Logic; dbug_0 : in Std_Logic; dbug_1 : in Std_Logic; dbug_dout : out Std_Logic ); END yfpga; ARCHITECTURE fpga OF yfpga IS SIGNAL hbus_datain : Std_Logic_Vector(15 downto 0); SIGNAL hbus_rd_data : Std_Logic_Vector(15 downto 0); SIGNAL amod, areg : Std_Logic_Vector(3 downto 0); SIGNAL host_reg_addr : Std_Logic_Vector(7 downto 0); SIGNAL host_mod_addr : Std_Logic_Vector(3 downto 0); SIGNAL host_rd_reg : Boolean; SIGNAL host_call_fun : Boolean; SIGNAL host_rd_reg0 : Boolean; SIGNAL host_rd_reg1 : Boolean; SIGNAL host_rd_reg2 : Boolean; SIGNAL host_rd_reg3 : Boolean; SIGNAL host_wr_reg : Boolean; SIGNAL host_wr_reg0 : Boolean; SIGNAL host_wr_reg1 : Boolean; SIGNAL host_wr_reg2 : Boolean; SIGNAL host_wr_reg3 : Boolean; SIGNAL host_call_fun0 : Boolean; SIGNAL host_call_fun1 : Boolean; SIGNAL host_call_fun2 : Boolean; SIGNAL host_call_fun3 : Boolean; SIGNAL host_fun_return : Std_Logic; SIGNAL Clock : Std_Logic; SIGNAL areg0, areg1 : Boolean; SIGNAL areg2, areg3 : Boolean; SIGNAL host_wr_id : Boolean; SIGNAL host_rd_status : Boolean; SIGNAL host_mod_status : Std_Logic; SIGNAL hbus_selectout : Std_Logic; SIGNAL hbus_selectin : Std_Logic; SIGNAL hbus_selecten : Boolean; SIGNAL dataarg, addrarg : Std_Logic_Vector(15 downto 0); SIGNAL xready : Std_Logic; SIGNAL sclk : Std_Logic; SIGNAL ok : Std_Logic; SIGNAL xfun : Std_Logic_Vector(1 downto 0); SIGNAL finished : Boolean; COMPONENT hif_444 PORT ( hbus_datain : in Std_Logic_Vector(15 downto 0); hbus_selectin : in Std_Logic; hbus_selectout : out Std_Logic; hbus_selecten : out Boolean; hbus_func : in Std_Logic_Vector(3 downto 0); hbus_ok : out Std_Logic; host_reg_addr : out Std_Logic_Vector(7 downto 0); host_mod_addr : inout Std_Logic_Vector(3 downto 0); host_rd_reg : inout Boolean; host_call_fun : inout Boolean; host_rd_reg0 : out Boolean; host_rd_reg1 : out Boolean; host_rd_reg2 : out Boolean; host_rd_reg3 : out Boolean; host_wr_reg : inout Boolean; host_wr_reg0 : out Boolean; host_wr_reg1 : out Boolean; host_wr_reg2 : out Boolean; host_wr_reg3 : out Boolean; host_call_fun0 : out Boolean; host_call_fun1 : out Boolean; host_call_fun2 : out Boolean; host_call_fun3 : out Boolean; host_fun_return : in Std_Logic; host_mod_status : in Std_Logic; C : in Std_Logic ); END COMPONENT; COMPONENT cup8h Port ( D : in Bit_Vector(7 downto 0); -- Input data PE : in Bit; -- Parallel load enable C : in Bit; -- Clock input CE : in Bit; -- Clock enable input RD : in Bit; -- Reset direct Q : out Bit_Vector(7 downto 0); -- Output data TC : out Bit); -- Terminal count flag END COMPONENT; SIGNAL stc, TC, CE, RD, C : Bit; SIGNAL Q : Bit_Vector(7 downto 0); SIGNAL clkreg : Bit_Vector(7 downto 0); SIGNAL tstreg : Bit_Vector(7 downto 0); SIGNAL host_wr_reg0_d : Boolean; TYPE StateVec IS (IDLE, NOP, RIDLE, WIDLE, READ1, WRITE1, READ2, WRITE2, READ3, WRITE3, READ4, WRITE4); SIGNAL State : StateVec; CONSTANT XIDLE : Std_Logic_Vector := "00"; CONSTANT XREAD : Std_Logic_Vector := "01"; CONSTANT XWRITE : Std_Logic_Vector := "10"; -- pragma synthesis_off FOR h: hif_444 USE ENTITY work.hif_444(fpga); FOR p: cup8h USE ENTITY work.cup8h(behavior); -- pragma synthesis_on BEGIN pq_func(10) <= 'Z'; hbus_datain <= hbus_data; pq_addr_e_b <= '0'; pq_data_e_b <= '0'; xbus0_e_b <= '1'; xbus1_e_b <= '1'; xbus2_e_b <= '1'; xbus3_e_b <= '1'; h: hif_444 PORT MAP( hbus_datain, hbus_selectin, hbus_selectout, hbus_selecten, hbus_func, ok, host_reg_addr, host_mod_addr, host_rd_reg, host_call_fun, host_rd_reg0, host_rd_reg1, host_rd_reg2, host_rd_reg3, host_wr_reg, host_wr_reg0, host_wr_reg1, host_wr_reg2, host_wr_reg3, host_call_fun0, host_call_fun1, host_call_fun2, host_call_fun3, host_fun_return, host_mod_status, Clock); Clock <= hbus_clk; C <= '1' WHEN Clock = '1' ELSE '0'; hbus_datain <= hbus_data; -- Create a programmable clock for xfpga: RD <= '0'; CE <= '1'; -- tstreg <= "111111" & clkreg(1 downto 0); p: cup8h port map ( clkreg, stc, C, CE, RD, Q, TC ); PROCESS BEGIN WAIT UNTIL Clock'event AND Clock = '1'; IF tc = '1' OR host_wr_reg0 THEN -- provide single-stepping stc <= '1'; -- of XFPGA clock ELSE stc <= '0'; END IF; -- program clockgen with a write to reg0 host_wr_reg0_d <= host_wr_reg0; IF host_wr_reg0 THEN clkreg <= To_BitVector(hbus_data(7 downto 0)); END IF; IF tc = '1' AND NOT host_wr_reg1 THEN pq_sclk <= '1'; ELSE pq_sclk <= '0'; END IF; END PROCESS; -- WARNING: the following comments may be a little old, but the -- general idea holds: -- Make state machine for function calls (READS and WRITES to XFPGA): -- follow hbus protocol: READ (fun0) -- cycle 0: hbus_fun = FUN, hbus_data = mod_addr -- cycle 1: hbus_fun = NOP, hbus_data = function number -- READ 2: qmem_addr = address, qmem_fun = XREAD1 -- READ 3: while xready != 1, goto READ3, else -- READ 4: data = qmem_data, qmem_fun = IDLE -- cycle 5: hbus_data <= data, hbus_ok = 1, goto idle -- follow hbus protocol: WRITE (fun1) -- cycle 0: hbus_fun = FUN, hbus_data = mod_addr -- cycle 1: hbus_fun = NOP, hbus_data = function number -- WRITE 2: hbus_data = address -- WRITE 3: hbus_data = wdata, qmem_addr = address, qmem_fun = XWRITE -- WRITE 4: while xready != 1, goto WRITE4, else -- WRITE 5: data = qmem_data, qmem_fun = IDLE -- cycle 6: hbus_data <= data, hbus_ok = 1, goto idle hbus_data <= hbus_rd_data WHEN ok = '1' AND NOT host_rd_reg2 ELSE "00000000" & To_StdLogicVector(clkreg) WHEN ok = '1' AND host_rd_reg2 ELSE "ZZZZZZZZZZZZZZZZ"; host_fun_return <= '1' WHEN (State = READ4) OR (State = WRITE4) ELSE '0'; hbus_ok <= ok; -- need to fix this to support multiple mods hbus_select <= hbus_selectout WHEN hbus_selecten ELSE 'Z'; hbus_selectin <= hbus_select; host_mod_status <= '0'; pmem_data <= dataarg WHEN (State = WRITE3) OR (State = WRITE4) ELSE "ZZZZZZZZZZZZZZZZ"; pmem_addr <= addrarg(15 downto 6); pq_func(5 downto 0) <= addrarg(5 downto 0); pq_func(8 downto 7) <= xfun; xready <= pq_func(10); finished <= xready = '1'; PROCESS BEGIN WAIT UNTIL Clock'event AND Clock = '1'; CASE State IS WHEN IDLE => -- the "host_call_funX" signal is active in the second bus clock (cycle 1) -- fun0 call: perform a read cycle IF host_call_fun0 THEN -- insure mutual exclusion IF NOT finished THEN State <= READ2; ELSE State <= RIDLE; END IF; -- fun1 call: perform a write cycle ELSIF host_call_fun1 THEN IF NOT finished THEN State <= WRITE2; ELSE State <= WIDLE; END IF; END IF; WHEN RIDLE => IF NOT finished THEN State <= READ2; END IF; WHEN WIDLE => IF NOT finished THEN State <= WRITE2; END IF; -- read sequence: WHEN READ2 => addrarg <= hbus_data; State <= READ3; xfun <= XREAD; WHEN READ3 => IF xready = '1' THEN State <= READ4; xfun <= XIDLE; hbus_rd_data <= pmem_data; ELSE State <= READ3; END IF; WHEN READ4 => State <= IDLE; -- write sequence: WHEN WRITE2 => addrarg <= hbus_data; State <= WRITE3; WHEN WRITE3 => xfun <= XWRITE; State <= WRITE4; dataarg <= hbus_data; WHEN WRITE4 => IF xready = '1' THEN State <= IDLE; xfun <= XIDLE; ELSE State <= WRITE4; END IF; WHEN OTHERS => State <= IDLE; END CASE; END PROCESS; END;