library ieee; library work; use ieee.std_logic_1164.all; use work.EtatPak.all; entity DialogueCPU is port ( RD, WR, A0, CS: in std_logic; clk : in std_logic; sortie : out std_logic; D : inout std_logic_vector(7 downto 0) := "ZZZZZZZZ"; d_buf_out : in std_logic_vector(15 downto 0); d_buf_in : out std_logic_vector(15 downto 0); charge_d, latch_d : out std_logic ) ; end DialogueCPU ; architecture archDialogueCPU of DialogueCPU is signal EtatW, EtatR : state := L; signal ctrlWord : std_logic_vector(7 downto 0) ; alias RW_op : std_logic_vector(1 downto 0) is ctrlWord(5 downto 4); alias D_RW : std_logic_vector(1 downto 0) is D(5 downto 4); alias d_buf_inMSB : std_logic_vector(7 downto 0) is d_buf_in(15 downto 8); alias d_buf_inLSB : std_logic_vector(7 downto 0) is d_buf_in( 7 downto 0); alias d_buf_outMSB : std_logic_vector(7 downto 0) is d_buf_out(15 downto 8); alias d_buf_outLSB : std_logic_vector(7 downto 0) is d_buf_out( 7 downto 0); begin --sortie <= '0' when (WR = '1') and (RD = '0') and (A0 = '0') and ((D_RW = Least) or (D_RW = Most) or (D_RW = LeastMost)) else '1'; sortie <= '0' when (WR = '1') and (RD = '0') and ( ((A0 = '1') and ((D_RW = Least) or (D_RW = Most) or (D_RW = LeastMost))) or (A0 = '0') ) else '1'; ReceptData : process(CS) begin if rising_edge(CS) then if ((WR = '1') and (RD = '0') and (A0 = '1')) then -- Reception ctrl D <= "ZZZZZZZZ"; charge_d <= '0'; if (D_RW = Latch) then latch_d <= '1'; --sortie <= '1'; else RW_op <= D_RW; latch_d <= '0'; --sortie <= '0'; if D_RW = Most then EtatW <= M; EtatR <= M; else EtatW <= L; EtatR <= L; end if ; end if ; elsif((WR = '1') and (RD = '0') and (A0 = '0')) then -- reception data D <= "ZZZZZZZZ"; if EtatW = L then d_buf_inLSB <= D; if (RW_op = LeastMost) then EtatW <= M; charge_d <= '0'; elsif (RW_op = Least) then d_buf_inMSB <= x"00"; charge_d <= '1'; end if ; elsif EtatW = M then d_buf_inMSB <= D; if (RW_op = LeastMost) then EtatW <= L; charge_d <= '1'; elsif (RW_op = Most) then charge_d <= '1'; d_buf_inLSB <= x"00"; end if ; else end if ; elsif ((WR = '0') and (RD = '1') and (A0 = '0')) then -- envoie data charge_d <= '0'; if EtatR = L then D <= d_buf_outLSB; if RW_op = LeastMost then EtatR <= M; elsif RW_op = Most then latch_d <= '0'; end if ; elsif EtatR = M then D <= d_buf_outMSB; if RW_op = LeastMost then EtatR <= L; latch_d <= '0'; elsif RW_op = Most then latch_d <= '0'; end if ; end if ; else end if ; end if ; end process ; -- ReceptData -- Pro_Etat_W : process -- begin -- end process ; -- Pro_Etat_W -- Pro_Etat_R : process -- begin -- end process ; -- Pro_Etat_R end architecture ; -- archDialogueCPU architecture archImplantation of DialogueCPU is signal EtatW_q, EtatR_q : state := L; signal EtatW, EtatR : state; signal ctrlWord : std_logic_vector(7 downto 0) := x"00"; alias RW_op : std_logic_vector(1 downto 0) is ctrlWord(5 downto 4); alias d_buf_outMSB : std_logic_vector(7 downto 0) is d_buf_out(15 downto 8); alias d_buf_outLSB : std_logic_vector(7 downto 0) is d_buf_out( 7 downto 0); constant inputVectWidth : integer := 46; COMPONENT DFFEXb generic(width : integer := inputVectWidth); port ( clk : in std_logic; Din : in std_logic_vector((width-1) downto 0) ; Q : out std_logic_vector((width-1) downto 0) ) ; end COMPONENT; signal inputVect : std_logic_vector((inputVectWidth-1) downto 0) ; signal outputVect : std_logic_vector((inputVectWidth-1) downto 0) := (OTHERS => '0'); signal latch_d_temp : std_logic; signal d_buf_in_temp : std_logic_vector(15 downto 0) ; alias D_q : std_logic_vector(7 downto 0) is outputVect(7 downto 0); alias D_RW_q : std_logic_vector(1 downto 0) is outputVect(5 downto 4) ; alias RD_q : std_logic is outputVect(8) ; alias WR_q : std_logic is outputVect(9) ; alias A0_q : std_logic is outputVect(10) ; alias d_buf_q : std_logic_vector(15 downto 0) is outputVect(26 downto 11) ; alias RW_op_q : std_logic_vector(1 downto 0) is outputVect(28 downto 27) ; alias latch_d_q : std_logic is outputVect(29); alias d_buf_inLSB_q : std_logic_vector(7 downto 0) is outputVect(37 downto 30) ; alias d_buf_inMSB_q : std_logic_vector(7 downto 0) is outputVect(45 downto 38) ; alias d_buf_in_tempLSB : std_logic_vector(7 downto 0) is d_buf_in_temp( 7 downto 0); alias d_buf_in_tempMSB : std_logic_vector(7 downto 0) is d_buf_in_temp(15 downto 8); begin -- avoid using a buffer in the declaration of the entity latch_d <= latch_d_temp; d_buf_in <= d_buf_in_temp; -- signals required to set the output signal of the entity stored in the same vector (whitout EtatW annd EtatR because there aren't std_logic) inputVect <= (d_buf_in_temp & latch_d_temp & RW_op & d_buf_out & A0 & WR & RD & D) ; bascule_D_CS : DFFEXb PORT MAP(CS, inputVect, outputVect); -- dedicated DFF to store EtatR and EtatW DFF_Etats_W_R : process( CS ) begin if rising_edge(CS) then EtatW_q <= EtatW; EtatR_q <= EtatR; end if ; end process ; -- DFF_Etats_W_R -- output functions -- '0' force the output of the timer to 0, '1' allow the counter to modify the output of the timer Sortie <= '0' when ((WR_q='1') and (RD_q='0') and ( ((A0_q = '1') and not(D_RW_q=Latch)) --Receive controle word without counter latch command or ((A0_q = '0') and (CS = '1')) --Load data in the counter )) else '1'; -- '0' = false, '1' = true charge_d <= '1' when ((CS = '1') and (WR_q='1') and (RD_q='0') and (A0_q = '0') and ( -- test if instruction is a load of counter ((EtatW_q = L) and (RW_op_q = Least)) -- if instruction load only lsb bytes or ((EtatW_q = M) and ((RW_op_q = Most) or (RW_op_q = LeastMost))) -- if instruction load only msb bytes or all bytes (and reading MSB bytes) )) else '0'; latch_d_temp <= '1' when ((WR_q='1') and (RD_q='0') and (A0_q = '1') and (D_RW_q=Latch)) -- if instruction is writing a control world else '0' when (((WR_q='0') and (RD_q='1') and (A0_q = '0') and ( -- test if instruction is a read of counter ((EtatW_q = L) and (RW_op_q = Least)) -- if instruction readonly lsb bytes or ((EtatW_q = M) and ((RW_op_q = Most) or (RW_op_q = LeastMost))) -- if instruction readonly msb bytes or all bytes (and reading MSB bytes) )) or ((WR_q='1') and (RD_q='0') and (A0_q = '1') and (not(D_RW_q=Latch))) -- if instruction is writing a control world without latch as RW command ) else latch_d_q; -- keep the previous value of latch RW_op <= D_RW_q when ((WR_q='1') and (RD_q='0') and (A0_q = '1') and (not(D_RW_q=Latch))) -- if instruction is writing a control world without latch as RW command else RW_op_q; -- keep the previous value of RW_op d_buf_in_tempLSB <= D_q when ((WR_q='1') and (RD_q='0') and (A0_q = '0') and (EtatW_q = L)) -- transfer of the LSB from D to d_buf_in(7 downto 0) else "00000000" when ((WR_q='1') and (RD_q='0') and (A0_q = '0') and (EtatW_q = M) and (RW_op_q = Most)) -- if we only load the MSB force x"00" to d_buf_in(7 downto 0) else d_buf_inLSB_q; -- keep the previous value of the variable d_buf_in_tempMSB <= D_q when ((WR_q='1') and (RD_q='0') and (A0_q = '0') and (EtatW_q = M)) -- transfer of the MSB from D to d_buf_in(15 downto 8) else "00000000" when ((WR_q='1') and (RD_q='0') and (A0_q = '0') and (EtatW_q = L) and (RW_op_q = Least)) -- if we only load the MSB force x"00" to d_buf_in(15 downto 8) else d_buf_inMSB_q; -- keep the previous value of the variable -- the CPU maintain (WR='0') and (RD='1') to keep value of dbuf_out on D if the CPU prepare an other instruction dialogue CPU set D as HiZ so the CPU can write on it D <= d_buf_outLSB when ((CS = '1') and (WR_q='0') and (RD_q='1') and (A0_q = '0') and (EtatW_q = L)) -- transfer of the LSB from d_buf_out( 7 downto 0) to D else d_buf_outMSB when ((CS = '1') and (WR_q='0') and (RD_q='1') and (A0_q = '0') and (EtatW_q = M) and (WR='0') and (RD='1')) -- transfer of the MSB from d_buf_out(15 downto 8) to D else "ZZZZZZZZ"; -- other instruction does not impact the bus EtatW <= M when (((WR_q='1') and (RD_q='0') and (A0_q = '0') and (EtatW_q = L) and (RW_op_q = LeastMost)) -- if loading in leastMost mode and EtatW_q = L or ((WR_q='1') and (RD_q='0') and (A0_q = '1') and (D_RW_q = Most))) -- if writing control word D_RW and mode is leastMost or Least else L when (((WR_q='1') and (RD_q='0') and (A0_q = '0') and (EtatW_q = M) and (RW_op_q = LeastMost)) -- if loading in leastMost mode and EtatW_q = M or ((WR_q='1') and (RD_q='0') and (A0_q = '1') and ((D_RW_q = LeastMost) or (D_RW_q = Least)))) -- if writing control word D_RW and mode is Most else EtatW_q; -- keep previous value EtatR <= M when (((WR_q='0') and (RD_q='1') and (A0_q = '0') and (EtatW_q = L) and (RW_op_q = LeastMost)) -- if reading in leastMost mode and EtatW_q = L or ((WR_q='1') and (RD_q='0') and (A0_q = '1') and (D_RW_q = Most))) -- if writing control word D_RW and mode is leastMost or Least else L when (((WR_q='0') and (RD_q='1') and (A0_q = '0') and (EtatW_q = M) and (RW_op_q = LeastMost)) -- if reading in leastMost mode and EtatW_q = M or ((WR_q='1') and (RD_q='0') and (A0_q = '1') and ((D_RW_q = LeastMost) or (D_RW_q = Least)))) -- if writing control word D_RW and mode is Most else EtatR_q; -- keep previous value end archImplantation ; -- archImplantation architecture archFSM of DialogueCPU is type stateFSM is( CS1, CS0 ); signal state_c : stateFSM := CS0; signal state_f : stateFSM := CS0; signal EtatW_q, EtatR_q : state := L; signal EtatW, EtatR : state; signal ctrlWord : std_logic_vector(7 downto 0) := x"00"; alias RW_op : std_logic_vector(1 downto 0) is ctrlWord(5 downto 4); alias D_RW : std_logic_vector(1 downto 0) is D(5 downto 4); alias d_buf_outMSB : std_logic_vector(7 downto 0) is d_buf_out(15 downto 8); alias d_buf_outLSB : std_logic_vector(7 downto 0) is d_buf_out( 7 downto 0); constant inputVectWidth : integer := 46; COMPONENT DFFEXb generic(width : integer := inputVectWidth); port ( clk : in std_logic; Din : in std_logic_vector((width-1) downto 0) ; Q : out std_logic_vector((width-1) downto 0) ) ; end COMPONENT; signal inputVect : std_logic_vector((inputVectWidth-1) downto 0) ; signal outputVect : std_logic_vector((inputVectWidth-1) downto 0) := (OTHERS => '0'); signal latch_d_temp : std_logic; signal d_buf_in_temp : std_logic_vector(15 downto 0) ; alias D_q : std_logic_vector(7 downto 0) is outputVect(7 downto 0); alias D_RW_q : std_logic_vector(1 downto 0) is outputVect(5 downto 4) ; alias RD_q : std_logic is outputVect(8) ; alias WR_q : std_logic is outputVect(9) ; alias A0_q : std_logic is outputVect(10) ; alias d_buf_q : std_logic_vector(15 downto 0) is outputVect(26 downto 11) ; alias RW_op_q : std_logic_vector(1 downto 0) is outputVect(28 downto 27) ; alias latch_d_q : std_logic is outputVect(29); alias d_buf_inLSB_q : std_logic_vector(7 downto 0) is outputVect(37 downto 30) ; alias d_buf_inMSB_q : std_logic_vector(7 downto 0) is outputVect(45 downto 38) ; alias d_buf_in_tempLSB : std_logic_vector(7 downto 0) is d_buf_in_temp( 7 downto 0); alias d_buf_in_tempMSB : std_logic_vector(7 downto 0) is d_buf_in_temp(15 downto 8); begin -- avoid using a buffer in the declaration of the entity latch_d <= latch_d_temp; d_buf_in <= d_buf_in_temp; -- signals required to set the output signal of the entity stored in the same vector (whitout EtatW annd EtatR because there aren't std_logic) inputVect <= (d_buf_in_temp & latch_d_temp & RW_op & d_buf_out & A0 & WR & RD & D) ; bascule_D_CS : DFFEXb PORT MAP(clk, inputVect, outputVect); -- dedicated DFF to store EtatR and EtatW DFF_Etats_W_R : process( clk ) begin if rising_edge(clk) then EtatW_q <= EtatW; EtatR_q <= EtatR; end if ; end process ; -- DFF_Etats_W_R state_f <= CS1 when CS='1' else CS0; StateReg : process(clk) begin if rising_edge(clk) then state_c <= state_f; end if; end process; -- output functions -- '0' force the output of the timer to 0, '1' allow the counter to modify the output of the timer Sortie <= '0' when ((state_c=CS1) and (WR='1') and (RD='0') and ( ((A0 = '1') and not(D_RW=Latch)) --Receive controle word without counter latch command or ((A0 = '0')) --Load data in the counter )) else '1'; -- '0' = false, '1' = true charge_d <= '1' when ((state_c=CS1) and (WR='1') and (RD='0') and (A0 = '0') and ( -- test if instruction is a load of counter ((EtatW_q = L) and (RW_op_q = Least)) -- if instruction load only lsb bytes or ((EtatW_q = M) and ((RW_op_q = Most) or (RW_op_q = LeastMost))) -- if instruction load only msb bytes or all bytes (and reading MSB bytes) )) else '0'; latch_d_temp <= '1' when ((state_c=CS1) and(WR='1') and (RD='0') and (A0 = '1') and (D_RW=Latch)) -- if instruction is writing a control world else '0' when ((state_c=CS1) and (((WR='0') and (RD='1') and (A0 = '0') and ( -- test if instruction is a read of counter ((EtatW_q = L) and (RW_op_q = Least)) -- if instruction readonly lsb bytes or ((EtatW_q = M) and ((RW_op_q = Most) or (RW_op_q = LeastMost))) -- if instruction readonly msb bytes or all bytes (and reading MSB bytes) )) or ((WR='1') and (RD='0') and (A0 = '1') and (not(D_RW=Latch))) -- if instruction is writing a control world without latch as RW command )) else latch_d_q; -- keep the previous value of latch RW_op <= D_RW_q when ((state_c=CS1) and (WR='1') and (RD='0') and (A0 = '1') and (not(D_RW=Latch))) -- if instruction is writing a control world without latch as RW command else RW_op_q; -- keep the previous value of RW_op d_buf_in_tempLSB <= D_q when ((state_c=CS1) and (WR='1') and (RD='0') and (A0 = '0') and (EtatW_q = L)) -- transfer of the LSB from D to d_buf_in(7 downto 0) else "00000000" when ((state_c=CS1) and (WR='1') and (RD='0') and (A0 = '0') and (EtatW_q = M) and (RW_op_q = Most)) -- if we only load the MSB force x"00" to d_buf_in(7 downto 0) else d_buf_inLSB_q; -- keep the previous value of the variable d_buf_in_tempMSB <= D_q when ((state_c=CS1) and (WR='1') and (RD='0') and (A0 = '0') and (EtatW_q = M)) -- transfer of the MSB from D to d_buf_in(15 downto 8) else "00000000" when ((state_c=CS1) and (WR='1') and (RD='0') and (A0 = '0') and (EtatW_q = L) and (RW_op_q = Least)) -- if we only load the MSB force x"00" to d_buf_in(15 downto 8) else d_buf_inMSB_q; -- keep the previous value of the variable -- the CPU maintain (WR='0') and (RD='1') to keep value of dbuf_out on D if the CPU prepare an other instruction dialogue CPU set D as HiZ so the CPU can write on it D <= d_buf_outLSB when ((state_c=CS1) and (WR='0') and (RD='1') and (A0 = '0') and (EtatW_q = L)) -- transfer of the LSB from d_buf_out( 7 downto 0) to D else d_buf_outMSB when ((state_c=CS1) and (WR='0') and (RD='1') and (A0 = '0') and (EtatW_q = M) and (WR='0') and (RD='1')) -- transfer of the MSB from d_buf_out(15 downto 8) to D else "ZZZZZZZZ"; -- other instruction does not impact the bus EtatW <= M when((state_c=CS1) and (((WR='1') and (RD='0') and (A0 = '0') and (EtatW_q = L) and (RW_op_q = LeastMost)) -- if loading in leastMost mode and EtatW_q = L or ((WR='1') and (RD='0') and (A0 = '1') and (D_RW = Most)))) -- if writing control word D_RW and mode is leastMost or Least else L when ((state_c=CS1) and (((WR='1') and (RD='0') and (A0 = '0') and (EtatW_q = M) and (RW_op_q = LeastMost)) -- if loading in leastMost mode and EtatW_q = M or ((WR='1') and (RD='0') and (A0 = '1') and ((D_RW = LeastMost) or (D_RW = Least))))) -- if writing control word D_RW and mode is Most else EtatW_q; -- keep previous value EtatR <= M when ((state_c=CS1) and (((WR='0') and (RD='1') and (A0 = '0') and (EtatW_q = L) and (RW_op_q = LeastMost)) -- if reading in leastMost mode and EtatW_q = L or ((WR='1') and (RD='0') and (A0 = '1') and (D_RW = Most)))) -- if writing control word D_RW and mode is leastMost or Least else L when ((state_c=CS1) and (((WR='0') and (RD='1') and (A0 = '0') and (EtatW_q = M) and (RW_op_q = LeastMost)) -- if reading in leastMost mode and EtatW_q = M or ((WR='1') and (RD='0') and (A0 = '1') and ((D_RW = LeastMost) or (D_RW = Least))))) -- if writing control word D_RW and mode is Most else EtatR_q; -- keep previous value end archFSM ; -- archImplantation