Newer
Older
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;
Bourgoin Thomas
committed
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);
) ;
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";
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;
elsif (RW_op = Least) then
d_buf_inMSB <= x"00";
end if ;
elsif EtatW = M then
d_buf_inMSB <= D;
if (RW_op = LeastMost) then
EtatW <= L;
d_buf_inLSB <= x"00";
end if ;
else
end if ;
elsif ((WR = '0') and (RD = '1') and (A0 = '0')) then -- envoie data
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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);
-- 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
Bourgoin Thomas
committed
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
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
Bourgoin Thomas
committed
latch_d <= latch_d_q;
d_buf_in <= (d_buf_inMSB_q & d_buf_inLSB_q);
Bourgoin Thomas
committed
-- 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
Bourgoin Thomas
committed
DFF_Etats_W_R : process( clk, state_c, CS)
Bourgoin Thomas
committed
begin
Bourgoin Thomas
committed
if rising_edge(clk) and (state_c = CS1) and (CS = '0') then
Bourgoin Thomas
committed
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;
Bourgoin Thomas
committed
Bourgoin Thomas
committed
-- output functions
-- '0' force the output of the timer to 0, '1' allow the counter to modify the output of the timer
Bourgoin Thomas
committed
Sortie <= '0' when ((CS='1') and (WR='1') and (RD='0') and (
Bourgoin Thomas
committed
((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';
-- gérer la remise à 0 de latch_d_temps
Bourgoin Thomas
committed
latch_d_temp <= '1'
Bourgoin Thomas
committed
when ((CS='1') and(WR='1') and (RD='0') and (A0 = '1') and (D_RW=Latch)) -- if instruction is writing a control world
else '0' when ((CS='1') and (((WR='0') and (RD='1') and (A0 = '0') and ( -- test if instruction is a read of counter
((EtatR_q = L) and (RW_op_q = Least)) -- if instruction readonly lsb bytes
or ((EtatR_q = M) and ((RW_op_q = Most) or (RW_op_q = LeastMost))) -- if instruction readonly msb bytes or all bytes (and reading MSB bytes)
Bourgoin Thomas
committed
))
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
Bourgoin Thomas
committed
RW_op <= D_RW_q when ((CS='1') 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
Bourgoin Thomas
committed
else RW_op_q; -- keep the previous value of RW_op
d_buf_in_tempLSB <= D when ((CS='1') 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)
Bourgoin Thomas
committed
else "00000000" when ((CS='1') 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)
Bourgoin Thomas
committed
else d_buf_inLSB_q; -- keep the previous value of the variable
d_buf_in_tempMSB <= D when ((CS='1') 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)
Bourgoin Thomas
committed
else "00000000" when ((CS='1') 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)
Bourgoin Thomas
committed
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 (EtatR_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 (EtatR_q = M)) -- transfer of the MSB from d_buf_out(15 downto 8) to D
Bourgoin Thomas
committed
else "ZZZZZZZZ"; -- other instruction does not impact the bus
-- rd_q ? yes so they are only update when state_c = CS1 and CS = 0 (at the end of the instruction) only input use as a condition and change in the same instruction
-- Pay attention to not update too early and Msb are modified wheras only LSB should have been
Bourgoin Thomas
committed
EtatW <= M when((state_c=CS1) and (((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
Bourgoin Thomas
committed
Bourgoin Thomas
committed
else L when ((state_c=CS1) and (((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
Bourgoin Thomas
committed
else EtatW_q; -- keep previous value
EtatR <= M when ((state_c=CS1) and (((WR_q='0') and (RD_q='1') and (A0_q = '0') and (EtatR_q = L) and (RW_op_q = LeastMost)) -- if reading in leastMost mode and EtatW_q = L
Bourgoin Thomas
committed
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
Bourgoin Thomas
committed
else L when ((state_c=CS1) and (((WR_q='0') and (RD_q='1') and (A0_q = '0') and (EtatR_q = M) and (RW_op_q = LeastMost)) -- if reading in leastMost mode and EtatW_q = M
Bourgoin Thomas
committed
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
Bourgoin Thomas
committed
else EtatR_q; -- keep previous value
end archFSM ; -- archImplantation