1 |
2 |
tobil |
--************************************************************************************************
|
2 |
|
|
-- PM_FETCH_DEC(internal module) for AVR core
|
3 |
|
|
-- Version 2.6! (Special version for the JTAG OCD)
|
4 |
|
|
-- Designed by Ruslan Lepetenok 14.11.2001
|
5 |
|
|
-- Modified 31.05.06
|
6 |
|
|
-- Modification:
|
7 |
|
|
-- Registered ramre/ramwe outputs
|
8 |
|
|
-- cpu_busy logic modified(affects RCALL/ICALL/CALL instruction interract with interrupt)
|
9 |
|
|
-- SLEEP and CLRWDT instructions support was added
|
10 |
|
|
-- V-flag bug fixed (AND/ANDI/OR/ORI/EOR)
|
11 |
|
|
-- V-flag bug fixed (ADIW/SBIW)
|
12 |
|
|
-- Unused outputs(sreg_bit_num[2..0],idc_sbi_out,idc_cbi_out,idc_bld_out) were removed.
|
13 |
|
|
-- Output alu_data_d_in[7..0] was removed.
|
14 |
|
|
-- Gloabal clock enable(cp2en) was added
|
15 |
|
|
-- cpu_busy(push/pop) + irq bug was fixed 14.07.05
|
16 |
|
|
-- BRXX+IRQ interaction was modified -> cpu_busy
|
17 |
|
|
-- LDS/STS now requires only two cycles for execution (13.01.06 -> last modificatioon)
|
18 |
|
|
--************************************************************************************************
|
19 |
|
|
|
20 |
|
|
library IEEE;
|
21 |
|
|
use IEEE.std_logic_1164.all;
|
22 |
|
|
use IEEE.std_logic_unsigned.all;
|
23 |
|
|
|
24 |
|
|
use WORK.AVRuCPackage.all;
|
25 |
|
|
|
26 |
|
|
entity pm_fetch_dec is port(
|
27 |
|
|
-- Clock and reset
|
28 |
|
|
cp2 : in std_logic;
|
29 |
|
|
cp2en : in std_logic;
|
30 |
|
|
ireset : in std_logic;
|
31 |
|
|
-- JTAG OCD support
|
32 |
|
|
valid_instr : out std_logic;
|
33 |
|
|
insert_nop : in std_logic;
|
34 |
|
|
block_irq : in std_logic;
|
35 |
|
|
change_flow : out std_logic;
|
36 |
|
|
-- Program memory
|
37 |
|
|
pc : out std_logic_vector (15 downto 0);
|
38 |
|
|
inst : in std_logic_vector (15 downto 0);
|
39 |
|
|
-- I/O control
|
40 |
|
|
adr : out std_logic_vector (5 downto 0);
|
41 |
|
|
iore : out std_logic;
|
42 |
|
|
iowe : out std_logic;
|
43 |
|
|
-- Data memory control
|
44 |
|
|
ramadr : out std_logic_vector (15 downto 0);
|
45 |
|
|
ramre : out std_logic;
|
46 |
|
|
ramwe : out std_logic;
|
47 |
|
|
cpuwait : in std_logic;
|
48 |
|
|
-- Data paths
|
49 |
|
|
dbusin : in std_logic_vector (7 downto 0);
|
50 |
|
|
dbusout : out std_logic_vector (7 downto 0);
|
51 |
|
|
dbusout_int_route : out std_logic_vector (7 downto 0);
|
52 |
|
|
-- Interrupt
|
53 |
|
|
irqlines : in std_logic_vector (22 downto 0);
|
54 |
|
|
irqack : out std_logic;
|
55 |
|
|
irqackad : out std_logic_vector(4 downto 0);
|
56 |
|
|
--Sleep
|
57 |
|
|
sleepi : out std_logic;
|
58 |
|
|
irqok : out std_logic;
|
59 |
|
|
--Watchdog
|
60 |
|
|
wdri : out std_logic;
|
61 |
|
|
-- ALU interface(Data inputs)
|
62 |
|
|
alu_data_r_in : out std_logic_vector(7 downto 0);
|
63 |
|
|
-- ALU interface(Instruction inputs)
|
64 |
|
|
idc_add_out : out std_logic;
|
65 |
|
|
idc_adc_out : out std_logic;
|
66 |
|
|
idc_adiw_out : out std_logic;
|
67 |
|
|
idc_sub_out : out std_logic;
|
68 |
|
|
idc_subi_out : out std_logic;
|
69 |
|
|
idc_sbc_out : out std_logic;
|
70 |
|
|
idc_sbci_out : out std_logic;
|
71 |
|
|
idc_sbiw_out : out std_logic;
|
72 |
|
|
|
73 |
|
|
adiw_st_out : out std_logic;
|
74 |
|
|
sbiw_st_out : out std_logic;
|
75 |
|
|
|
76 |
|
|
idc_and_out : out std_logic;
|
77 |
|
|
idc_andi_out : out std_logic;
|
78 |
|
|
idc_or_out : out std_logic;
|
79 |
|
|
idc_ori_out : out std_logic;
|
80 |
|
|
idc_eor_out : out std_logic;
|
81 |
|
|
idc_com_out : out std_logic;
|
82 |
|
|
idc_neg_out : out std_logic;
|
83 |
|
|
|
84 |
|
|
idc_inc_out : out std_logic;
|
85 |
|
|
idc_dec_out : out std_logic;
|
86 |
|
|
|
87 |
|
|
idc_cp_out : out std_logic;
|
88 |
|
|
idc_cpc_out : out std_logic;
|
89 |
|
|
idc_cpi_out : out std_logic;
|
90 |
|
|
idc_cpse_out : out std_logic;
|
91 |
|
|
|
92 |
|
|
idc_lsr_out : out std_logic;
|
93 |
|
|
idc_ror_out : out std_logic;
|
94 |
|
|
idc_asr_out : out std_logic;
|
95 |
|
|
idc_swap_out : out std_logic;
|
96 |
|
|
|
97 |
|
|
-- ALU interface(Data output)
|
98 |
|
|
alu_data_out : in std_logic_vector(7 downto 0);
|
99 |
|
|
|
100 |
|
|
-- ALU interface(Flag outputs)
|
101 |
|
|
alu_c_flag_out : in std_logic;
|
102 |
|
|
alu_z_flag_out : in std_logic;
|
103 |
|
|
alu_n_flag_out : in std_logic;
|
104 |
|
|
alu_v_flag_out : in std_logic;
|
105 |
|
|
alu_s_flag_out : in std_logic;
|
106 |
|
|
alu_h_flag_out : in std_logic;
|
107 |
|
|
|
108 |
|
|
-- General purpose register file interface
|
109 |
|
|
reg_rd_in : out std_logic_vector (7 downto 0);
|
110 |
|
|
reg_rd_out : in std_logic_vector (7 downto 0);
|
111 |
|
|
reg_rd_out_int : in std_logic_vector(7 downto 0);
|
112 |
|
|
reg_rd_adr : out std_logic_vector (4 downto 0);
|
113 |
|
|
reg_rd_adr_int : out std_logic_vector (4 downto 0);
|
114 |
|
|
reg_rr_out : in std_logic_vector (7 downto 0);
|
115 |
|
|
reg_rr_adr : out std_logic_vector (4 downto 0);
|
116 |
|
|
reg_rd_wr : out std_logic;
|
117 |
|
|
|
118 |
|
|
post_inc : out std_logic; -- POST INCREMENT FOR LD/ST INSTRUCTIONS
|
119 |
|
|
pre_dec : out std_logic; -- PRE DECREMENT FOR LD/ST INSTRUCTIONS
|
120 |
|
|
reg_h_wr : out std_logic;
|
121 |
|
|
reg_h_out : in std_logic_vector (15 downto 0);
|
122 |
|
|
reg_h_adr : out std_logic_vector (2 downto 0); -- x,y,z
|
123 |
|
|
reg_z_out : in std_logic_vector (15 downto 0); -- OUTPUT OF R31:R30 FOR LPM/ELPM/IJMP INSTRUCTIONS
|
124 |
|
|
|
125 |
|
|
-- I/O register file interface
|
126 |
|
|
sreg_fl_in : out std_logic_vector(7 downto 0);
|
127 |
|
|
globint : in std_logic; -- SREG I flag
|
128 |
|
|
|
129 |
|
|
sreg_fl_wr_en : out std_logic_vector(7 downto 0); --FLAGS WRITE ENABLE SIGNALS
|
130 |
|
|
|
131 |
|
|
spl_out : in std_logic_vector(7 downto 0);
|
132 |
|
|
sph_out : in std_logic_vector(7 downto 0);
|
133 |
|
|
sp_ndown_up : out std_logic; -- DIRECTION OF CHANGING OF STACK POINTER SPH:SPL 0->UP(+) 1->DOWN(-)
|
134 |
|
|
sp_en : out std_logic; -- WRITE ENABLE(COUNT ENABLE) FOR SPH AND SPL REGISTERS
|
135 |
|
|
|
136 |
|
|
rampz_out : in std_logic_vector(7 downto 0);
|
137 |
|
|
|
138 |
|
|
-- Bit processor interface
|
139 |
|
|
bit_num_r_io : out std_logic_vector (2 downto 0); -- BIT NUMBER FOR CBI/SBI/BLD/BST/SBRS/SBRC/SBIC/SBIS INSTRUCTIONS
|
140 |
|
|
bitpr_io_out : in std_logic_vector(7 downto 0); -- SBI/CBI OUT
|
141 |
|
|
branch : out std_logic_vector (2 downto 0); -- NUMBER (0..7) OF BRANCH CONDITION FOR BRBS/BRBC INSTRUCTION
|
142 |
|
|
bit_pr_sreg_out : in std_logic_vector(7 downto 0); -- BCLR/BSET/BST(T-FLAG ONLY)
|
143 |
|
|
bld_op_out : in std_logic_vector(7 downto 0); -- BLD OUT (T FLAG)
|
144 |
|
|
bit_test_op_out : in std_logic; -- OUTPUT OF SBIC/SBIS/SBRS/SBRC
|
145 |
|
|
|
146 |
|
|
sbi_st_out : out std_logic;
|
147 |
|
|
cbi_st_out : out std_logic;
|
148 |
|
|
|
149 |
|
|
idc_bst_out : out std_logic;
|
150 |
|
|
idc_bset_out : out std_logic;
|
151 |
|
|
idc_bclr_out : out std_logic;
|
152 |
|
|
|
153 |
|
|
idc_sbic_out : out std_logic;
|
154 |
|
|
idc_sbis_out : out std_logic;
|
155 |
|
|
|
156 |
|
|
idc_sbrs_out : out std_logic;
|
157 |
|
|
idc_sbrc_out : out std_logic;
|
158 |
|
|
|
159 |
|
|
idc_brbs_out : out std_logic;
|
160 |
|
|
idc_brbc_out : out std_logic;
|
161 |
|
|
|
162 |
|
|
idc_reti_out : out std_logic);
|
163 |
|
|
end pm_fetch_dec;
|
164 |
|
|
|
165 |
|
|
architecture RTL of pm_fetch_dec is
|
166 |
|
|
|
167 |
|
|
-- COPIES OF OUTPUTS
|
168 |
|
|
signal ramadr_reg_in : std_logic_vector(15 downto 0); -- INPUT OF THE ADDRESS REGISTER
|
169 |
|
|
signal ramadr_reg_en : std_logic; -- ADRESS REGISTER CLOCK ENABLE SIGNAL
|
170 |
|
|
|
171 |
|
|
signal irqack_int : std_logic;
|
172 |
|
|
signal irqackad_int : std_logic_vector(irqackad'range);
|
173 |
|
|
|
174 |
|
|
-- ####################################################
|
175 |
|
|
-- INTERNAL SIGNALS
|
176 |
|
|
-- ####################################################
|
177 |
|
|
|
178 |
|
|
-- NEW SIGNALS
|
179 |
|
|
signal two_word_inst : std_logic; -- CALL/JMP/STS/LDS INSTRUCTION INDICATOR
|
180 |
|
|
|
181 |
|
|
signal ram_adr_int : std_logic_vector (15 downto 0);
|
182 |
|
|
constant const_ram_to_reg : std_logic_vector := "00000000000"; -- LD/LDS/LDD/ST/STS/STD ADDRESSING GENERAL PURPOSE REGISTER (R0-R31) 0x00..0x19
|
183 |
|
|
constant const_ram_to_io_a : std_logic_vector := "00000000001"; -- LD/LDS/LDD/ST/STS/STD ADDRESSING GENERAL I/O PORT 0x20 0x3F
|
184 |
|
|
constant const_ram_to_io_b : std_logic_vector := "00000000010"; -- LD/LDS/LDD/ST/STS/STD ADDRESSING GENERAL I/O PORT 0x20 0x3F
|
185 |
|
|
|
186 |
|
|
-- LD/LDD/ST/STD SIGNALS
|
187 |
|
|
signal adiw_sbiw_encoder_out : std_logic_vector (4 downto 0);
|
188 |
|
|
signal adiw_sbiw_encoder_mux_out : std_logic_vector (4 downto 0);
|
189 |
|
|
|
190 |
|
|
|
191 |
|
|
-- PROGRAM COUNTER SIGNALS
|
192 |
|
|
signal program_counter_tmp : std_logic_vector (15 downto 0); -- TO STORE PC DURING LPM/ELPM INSTRUCTIONS
|
193 |
|
|
signal program_counter : std_logic_vector (15 downto 0);
|
194 |
|
|
signal program_counter_in : std_logic_vector (15 downto 0);
|
195 |
|
|
signal program_counter_high_fr : std_logic_vector (7 downto 0); -- TO STORE PC FOR CALL,IRQ,RCALL,ICALL
|
196 |
|
|
|
197 |
|
|
signal pc_low : std_logic_vector (7 downto 0);
|
198 |
|
|
signal pc_high : std_logic_vector (7 downto 0);
|
199 |
|
|
|
200 |
|
|
|
201 |
|
|
signal pc_low_en : std_logic;
|
202 |
|
|
signal pc_high_en : std_logic;
|
203 |
|
|
|
204 |
|
|
signal offset_brbx : std_logic_vector (15 downto 0); -- OFFSET FOR BRCS/BRCC INSTRUCTION !!CHECKED
|
205 |
|
|
signal offset_rxx : std_logic_vector (15 downto 0); -- OFFSET FOR RJMP/RCALL INSTRUCTION !!CHECKED
|
206 |
|
|
|
207 |
|
|
signal pa15_pm : std_logic; -- ADDRESS LINE 15 FOR LPM/ELPM INSTRUCTIONS ('0' FOR LPM,RAMPZ(0) FOR ELPM)
|
208 |
|
|
|
209 |
|
|
signal alu_reg_wr : std_logic; -- ALU INSTRUCTIONS PRODUCING WRITE TO THE GENERAL PURPOSE REGISTER FILE
|
210 |
|
|
|
211 |
|
|
-- DATA MEMORY,GENERAL PURPOSE REGISTERS AND I/O REGISTERS LOGIC
|
212 |
|
|
|
213 |
|
|
--! IMPORTANT NOTICE : OPERATIONS WHICH USE STACK POINTER (SPH:SPL) CAN NOT ACCCSESS GENERAL
|
214 |
|
|
-- PURPOSE REGISTER FILE AND INPUT/OUTPUT REGISTER FILE !
|
215 |
|
|
-- THESE OPERATIONS ARE : RCALL/ICALL/CALL/RET/RETI/PUSH/POP INSTRUCTIONS AND INTERRUPT
|
216 |
|
|
|
217 |
|
|
signal reg_file_adr_space : std_logic; -- ACCSESS TO THE REGISTER FILE
|
218 |
|
|
signal io_file_adr_space : std_logic; -- ACCSESS TO THE I/O FILE
|
219 |
|
|
|
220 |
|
|
-- STATE MACHINES SIGNALS
|
221 |
|
|
signal irq_start : std_logic;
|
222 |
|
|
|
223 |
|
|
signal nirq_st0 : std_logic;
|
224 |
|
|
signal irq_st1 : std_logic;
|
225 |
|
|
signal irq_st2 : std_logic;
|
226 |
|
|
signal irq_st3 : std_logic;
|
227 |
|
|
|
228 |
|
|
signal ncall_st0 : std_logic;
|
229 |
|
|
signal call_st1 : std_logic;
|
230 |
|
|
signal call_st2 : std_logic;
|
231 |
|
|
signal call_st3 : std_logic;
|
232 |
|
|
|
233 |
|
|
signal nrcall_st0 : std_logic;
|
234 |
|
|
signal rcall_st1 : std_logic;
|
235 |
|
|
signal rcall_st2 : std_logic;
|
236 |
|
|
|
237 |
|
|
signal nicall_st0 : std_logic;
|
238 |
|
|
signal icall_st1 : std_logic;
|
239 |
|
|
signal icall_st2 : std_logic;
|
240 |
|
|
|
241 |
|
|
signal njmp_st0 : std_logic;
|
242 |
|
|
signal jmp_st1 : std_logic;
|
243 |
|
|
signal jmp_st2 : std_logic;
|
244 |
|
|
|
245 |
|
|
signal ijmp_st : std_logic;
|
246 |
|
|
|
247 |
|
|
signal rjmp_st : std_logic;
|
248 |
|
|
|
249 |
|
|
signal nret_st0 : std_logic;
|
250 |
|
|
signal ret_st1 : std_logic;
|
251 |
|
|
signal ret_st2 : std_logic;
|
252 |
|
|
signal ret_st3 : std_logic;
|
253 |
|
|
|
254 |
|
|
signal nreti_st0 : std_logic;
|
255 |
|
|
signal reti_st1 : std_logic;
|
256 |
|
|
signal reti_st2 : std_logic;
|
257 |
|
|
signal reti_st3 : std_logic;
|
258 |
|
|
|
259 |
|
|
signal brxx_st : std_logic; -- BRANCHES
|
260 |
|
|
|
261 |
|
|
signal adiw_st : std_logic;
|
262 |
|
|
signal sbiw_st : std_logic;
|
263 |
|
|
|
264 |
|
|
signal nskip_inst_st0 : std_logic;
|
265 |
|
|
signal skip_inst_st1 : std_logic;
|
266 |
|
|
signal skip_inst_st2 : std_logic; -- ALL SKIP INSTRUCTIONS SBRS/SBRC/SBIS/SBIC/CPSE
|
267 |
|
|
|
268 |
|
|
signal skip_inst_start : std_logic;
|
269 |
|
|
|
270 |
|
|
signal nlpm_st0 : std_logic;
|
271 |
|
|
signal lpm_st1 : std_logic;
|
272 |
|
|
signal lpm_st2 : std_logic;
|
273 |
|
|
|
274 |
|
|
signal nelpm_st0 : std_logic;
|
275 |
|
|
signal elpm_st1 : std_logic;
|
276 |
|
|
signal elpm_st2 : std_logic;
|
277 |
|
|
|
278 |
|
|
--signal nsts_st0 : std_logic;
|
279 |
|
|
--signal sts_st1 : std_logic;
|
280 |
|
|
--signal sts_st2 : std_logic;
|
281 |
|
|
|
282 |
|
|
signal sts_st : std_logic;
|
283 |
|
|
|
284 |
|
|
--signal nlds_st0 : std_logic;
|
285 |
|
|
--signal lds_st1 : std_logic;
|
286 |
|
|
--signal lds_st2 : std_logic;
|
287 |
|
|
|
288 |
|
|
signal lds_st : std_logic;
|
289 |
|
|
|
290 |
|
|
signal st_st : std_logic;
|
291 |
|
|
signal ld_st : std_logic;
|
292 |
|
|
|
293 |
|
|
signal sbi_st : std_logic;
|
294 |
|
|
signal cbi_st : std_logic;
|
295 |
|
|
|
296 |
|
|
signal push_st : std_logic;
|
297 |
|
|
signal pop_st : std_logic;
|
298 |
|
|
|
299 |
|
|
-- INTERNAL STATE MACHINES
|
300 |
|
|
signal nop_insert_st : std_logic;
|
301 |
|
|
signal cpu_busy : std_logic;
|
302 |
|
|
|
303 |
|
|
-- INTERNAL COPIES OF OUTPUTS
|
304 |
|
|
signal pc_int : std_logic_vector (15 downto 0);
|
305 |
|
|
signal adr_int : std_logic_vector (5 downto 0);
|
306 |
|
|
signal iore_int : std_logic;
|
307 |
|
|
signal iowe_int : std_logic;
|
308 |
|
|
signal ramadr_int : std_logic_vector (15 downto 0);
|
309 |
|
|
signal ramre_int : std_logic;
|
310 |
|
|
signal ramwe_int : std_logic;
|
311 |
|
|
signal dbusout_int : std_logic_vector (7 downto 0);
|
312 |
|
|
|
313 |
|
|
-- COMMAND REGISTER
|
314 |
|
|
signal instruction_reg : std_logic_vector (15 downto 0); -- OUTPUT OF THE INSTRUCTION REGISTER
|
315 |
|
|
signal instruction_code_reg : std_logic_vector (15 downto 0); -- OUTPUT OF THE INSTRUCTION REGISTER WITH NOP INSERTION
|
316 |
|
|
signal instruction_reg_ena : std_logic; -- CLOCK ENABLE
|
317 |
|
|
|
318 |
|
|
|
319 |
|
|
-- IRQ INTERNAL LOGIC
|
320 |
|
|
signal irq_int : std_logic;
|
321 |
|
|
signal irq_vector_adr : std_logic_vector(15 downto 0);
|
322 |
|
|
|
323 |
|
|
-- INTERRUPT RELATING REGISTERS
|
324 |
|
|
signal pc_for_interrupt : std_logic_vector(15 downto 0);
|
325 |
|
|
|
326 |
|
|
-- DATA EXTRACTOR SIGNALS
|
327 |
|
|
signal dex_dat8_immed : std_logic_vector (7 downto 0); -- IMMEDIATE CONSTANT (DATA) -> ANDI,ORI,SUBI,SBCI,CPI,LDI
|
328 |
|
|
signal dex_dat6_immed : std_logic_vector (5 downto 0); -- IMMEDIATE CONSTANT (DATA) -> ADIW,SBIW
|
329 |
|
|
signal dex_adr12mem_s : std_logic_vector (11 downto 0); -- RELATIVE ADDRESS (SIGNED) -> RCALL,RJMP
|
330 |
|
|
signal dex_adr6port : std_logic_vector (5 downto 0); -- I/O PORT ADDRESS -> IN,OUT
|
331 |
|
|
signal dex_adr5port : std_logic_vector (4 downto 0); -- I/O PORT ADDRESS -> CBI,SBI,SBIC,SBIS
|
332 |
|
|
signal dex_adr_disp : std_logic_vector (5 downto 0); -- DISPLACEMENT FO ADDDRESS -> STD,LDD
|
333 |
|
|
signal dex_condition : std_logic_vector (2 downto 0); -- CONDITION -> BRBC,BRBS
|
334 |
|
|
signal dex_bitnum_sreg : std_logic_vector (2 downto 0); -- NUMBER OF BIT IN SREG -> BCLR,BSET
|
335 |
|
|
signal dex_adrreg_r : std_logic_vector (4 downto 0); -- SOURCE REGISTER ADDRESS -> .......
|
336 |
|
|
signal dex_adrreg_d : std_logic_vector (4 downto 0); -- DESTINATION REGISTER ADDRESS -> ......
|
337 |
|
|
signal dex_bitop_bitnum : std_logic_vector(2 downto 0); -- NUMBER OF BIT FOR BIT ORIENTEDE OPERATION -> BST/BLD+SBI/CBI+SBIC/SBIS+SBRC/SBRS !! CHECKED
|
338 |
|
|
signal dex_brxx_offset : std_logic_vector (6 downto 0); -- RELATIVE ADDRESS (SIGNED) -> BRBC,BRBS !! CHECKED
|
339 |
|
|
signal dex_adiw_sbiw_reg_adr : std_logic_vector (1 downto 0); -- ADDRESS OF THE LOW REGISTER FOR ADIW/SBIW INSTRUCTIONS
|
340 |
|
|
|
341 |
|
|
signal dex_adrreg_d_latched : std_logic_vector (4 downto 0); -- STORE ADDRESS OF DESTINATION REGISTER FOR LDS/STS/POP INSTRUCTIONS
|
342 |
|
|
signal gp_reg_tmp : std_logic_vector (7 downto 0); -- STORE DATA FROM THE REGISTERS FOR STS,ST INSTRUCTIONS
|
343 |
|
|
signal cbi_sbi_io_adr_tmp : std_logic_vector (4 downto 0); -- STORE ADDRESS OF I/O PORT FOR CBI/SBI INSTRUCTION
|
344 |
|
|
signal cbi_sbi_bit_num_tmp : std_logic_vector (2 downto 0); -- STORE ADDRESS OF I/O PORT FOR CBI/SBI INSTRUCTION
|
345 |
|
|
|
346 |
|
|
-- INSTRUCTIONS DECODER SIGNALS
|
347 |
|
|
|
348 |
|
|
signal idc_adc : std_logic; -- INSTRUCTION ADC
|
349 |
|
|
signal idc_add : std_logic; -- INSTRUCTION ADD
|
350 |
|
|
signal idc_adiw : std_logic; -- INSTRUCTION ADIW
|
351 |
|
|
signal idc_and : std_logic; -- INSTRUCTION AND
|
352 |
|
|
signal idc_andi : std_logic; -- INSTRUCTION ANDI
|
353 |
|
|
signal idc_asr : std_logic; -- INSTRUCTION ASR
|
354 |
|
|
|
355 |
|
|
signal idc_bclr : std_logic; -- INSTRUCTION BCLR
|
356 |
|
|
signal idc_bld : std_logic; -- INSTRUCTION BLD
|
357 |
|
|
signal idc_brbc : std_logic; -- INSTRUCTION BRBC
|
358 |
|
|
signal idc_brbs : std_logic; -- INSTRUCTION BRBS
|
359 |
|
|
signal idc_bset : std_logic; -- INSTRUCTION BSET
|
360 |
|
|
signal idc_bst : std_logic; -- INSTRUCTION BST
|
361 |
|
|
|
362 |
|
|
signal idc_call : std_logic; -- INSTRUCTION CALL
|
363 |
|
|
signal idc_cbi : std_logic; -- INSTRUCTION CBI
|
364 |
|
|
signal idc_com : std_logic; -- INSTRUCTION COM
|
365 |
|
|
signal idc_cp : std_logic; -- INSTRUCTION CP
|
366 |
|
|
signal idc_cpc : std_logic; -- INSTRUCTION CPC
|
367 |
|
|
signal idc_cpi : std_logic; -- INSTRUCTION CPI
|
368 |
|
|
signal idc_cpse : std_logic; -- INSTRUCTION CPSE
|
369 |
|
|
|
370 |
|
|
signal idc_dec : std_logic; -- INSTRUCTION DEC
|
371 |
|
|
|
372 |
|
|
signal idc_elpm : std_logic; -- INSTRUCTION ELPM
|
373 |
|
|
signal idc_eor : std_logic; -- INSTRUCTION EOR
|
374 |
|
|
|
375 |
|
|
signal idc_icall : std_logic; -- INSTRUCTION ICALL
|
376 |
|
|
signal idc_ijmp : std_logic; -- INSTRUCTION IJMP
|
377 |
|
|
|
378 |
|
|
signal idc_in : std_logic; -- INSTRUCTION IN
|
379 |
|
|
signal idc_inc : std_logic; -- INSTRUCTION INC
|
380 |
|
|
|
381 |
|
|
signal idc_jmp : std_logic; -- INSTRUCTION JMP
|
382 |
|
|
|
383 |
|
|
signal idc_ld_x : std_logic; -- INSTRUCTION LD Rx,X ; LD Rx,X+ ;LD Rx,-X
|
384 |
|
|
signal idc_ld_y : std_logic; -- INSTRUCTION LD Rx,Y ; LD Rx,Y+ ;LD Rx,-Y
|
385 |
|
|
signal idc_ldd_y : std_logic; -- INSTRUCTION LDD Rx,Y+q
|
386 |
|
|
signal idc_ld_z : std_logic; -- INSTRUCTION LD Rx,Z ; LD Rx,Z+ ;LD Rx,-Z
|
387 |
|
|
signal idc_ldd_z : std_logic; -- INSTRUCTION LDD Rx,Z+q
|
388 |
|
|
|
389 |
|
|
signal idc_ldi : std_logic; -- INSTRUCTION LDI
|
390 |
|
|
signal idc_lds : std_logic; -- INSTRUCTION LDS
|
391 |
|
|
signal idc_lpm : std_logic; -- INSTRUCTION LPM
|
392 |
|
|
signal idc_lsr : std_logic; -- INSTRUCTION LSR
|
393 |
|
|
|
394 |
|
|
signal idc_mov : std_logic; -- INSTRUCTION MOV
|
395 |
|
|
signal idc_mul : std_logic; -- INSTRUCTION MUL
|
396 |
|
|
|
397 |
|
|
signal idc_neg : std_logic; -- INSTRUCTION NEG
|
398 |
|
|
signal idc_nop : std_logic; -- INSTRUCTION NOP
|
399 |
|
|
|
400 |
|
|
signal idc_or : std_logic; -- INSTRUCTION OR
|
401 |
|
|
signal idc_ori : std_logic; -- INSTRUCTION ORI
|
402 |
|
|
signal idc_out : std_logic; -- INSTRUCTION OUT
|
403 |
|
|
|
404 |
|
|
signal idc_pop : std_logic; -- INSTRUCTION POP
|
405 |
|
|
signal idc_push : std_logic; -- INSTRUCTION PUSH
|
406 |
|
|
|
407 |
|
|
signal idc_rcall : std_logic; -- INSTRUCTION RCALL
|
408 |
|
|
signal idc_ret : std_logic; -- INSTRUCTION RET
|
409 |
|
|
signal idc_reti : std_logic; -- INSTRUCTION RETI
|
410 |
|
|
signal idc_rjmp : std_logic; -- INSTRUCTION RJMP
|
411 |
|
|
signal idc_ror : std_logic; -- INSTRUCTION ROR
|
412 |
|
|
|
413 |
|
|
signal idc_sbc : std_logic; -- INSTRUCTION SBC
|
414 |
|
|
signal idc_sbci : std_logic; -- INSTRUCTION SBCI
|
415 |
|
|
signal idc_sbi : std_logic; -- INSTRUCTION SBI
|
416 |
|
|
signal idc_sbic : std_logic; -- INSTRUCTION SBIC
|
417 |
|
|
signal idc_sbis : std_logic; -- INSTRUCTION SBIS
|
418 |
|
|
signal idc_sbiw : std_logic; -- INSTRUCTION SBIW
|
419 |
|
|
signal idc_sbrc : std_logic; -- INSTRUCTION SBRC
|
420 |
|
|
signal idc_sbrs : std_logic; -- INSTRUCTION SBRS
|
421 |
|
|
signal idc_sleep : std_logic; -- INSTRUCTION SLEEP
|
422 |
|
|
|
423 |
|
|
signal idc_st_x : std_logic; -- INSTRUCTION LD X,Rx ; LD X+,Rx ;LD -X,Rx
|
424 |
|
|
signal idc_st_y : std_logic; -- INSTRUCTION LD Y,Rx ; LD Y+,Rx ;LD -Y,Rx
|
425 |
|
|
signal idc_std_y : std_logic; -- INSTRUCTION LDD Y+q,Rx
|
426 |
|
|
signal idc_st_z : std_logic; -- INSTRUCTION LD Z,Rx ; LD Z+,Rx ;LD -Z,Rx
|
427 |
|
|
signal idc_std_z : std_logic; -- INSTRUCTION LDD Z+q,Rx
|
428 |
|
|
|
429 |
|
|
signal idc_sts : std_logic; -- INSTRUCTION STS
|
430 |
|
|
signal idc_sub : std_logic; -- INSTRUCTION SUB
|
431 |
|
|
signal idc_subi : std_logic; -- INSTRUCTION SUBI
|
432 |
|
|
signal idc_swap : std_logic; -- INSTRUCTION SWAP
|
433 |
|
|
|
434 |
|
|
signal idc_wdr : std_logic; -- INSTRUCTION WDR
|
435 |
|
|
|
436 |
|
|
-- ADDITIONAL SIGNALS
|
437 |
|
|
signal idc_psinc : std_logic; -- POST INCREMENT FLAG FOR LD,ST INSTRUCTIONS
|
438 |
|
|
signal idc_prdec : std_logic; -- PRE DECREMENT FLAG FOR LD,ST INSTRUCTIONS
|
439 |
|
|
|
440 |
|
|
-- ##################################################
|
441 |
|
|
|
442 |
|
|
-- SREG FLAGS WRITE ENABLE SIGNALS
|
443 |
|
|
|
444 |
|
|
--alias sreg_c_wr_en : std_logic is sreg_fl_wr_en(0);
|
445 |
|
|
--alias sreg_z_wr_en : std_logic is sreg_fl_wr_en(1);
|
446 |
|
|
--alias sreg_n_wr_en : std_logic is sreg_fl_wr_en(2);
|
447 |
|
|
--alias sreg_v_wr_en : std_logic is sreg_fl_wr_en(3);
|
448 |
|
|
--alias sreg_s_wr_en : std_logic is sreg_fl_wr_en(4);
|
449 |
|
|
--alias sreg_h_wr_en : std_logic is sreg_fl_wr_en(5);
|
450 |
|
|
--alias sreg_t_wr_en : std_logic is sreg_fl_wr_en(6);
|
451 |
|
|
--alias sreg_i_wr_en : std_logic is sreg_fl_wr_en(7);
|
452 |
|
|
|
453 |
|
|
signal sreg_c_wr_en : std_logic; -- is sreg_fl_wr_en(0);
|
454 |
|
|
signal sreg_z_wr_en : std_logic; -- is sreg_fl_wr_en(1);
|
455 |
|
|
signal sreg_n_wr_en : std_logic; -- is sreg_fl_wr_en(2);
|
456 |
|
|
signal sreg_v_wr_en : std_logic; -- is sreg_fl_wr_en(3);
|
457 |
|
|
signal sreg_s_wr_en : std_logic; -- is sreg_fl_wr_en(4);
|
458 |
|
|
signal sreg_h_wr_en : std_logic; -- is sreg_fl_wr_en(5);
|
459 |
|
|
signal sreg_t_wr_en : std_logic; -- is sreg_fl_wr_en(6);
|
460 |
|
|
signal sreg_i_wr_en : std_logic; -- is sreg_fl_wr_en(7);
|
461 |
|
|
|
462 |
|
|
signal sreg_bop_wr_en : std_logic_vector (7 downto 0);
|
463 |
|
|
|
464 |
|
|
signal sreg_adr_eq : std_logic;
|
465 |
|
|
-- &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
466 |
|
|
|
467 |
|
|
begin
|
468 |
|
|
|
469 |
|
|
sreg_fl_wr_en <= sreg_i_wr_en & sreg_t_wr_en & sreg_h_wr_en & sreg_s_wr_en & sreg_v_wr_en & sreg_n_wr_en & sreg_z_wr_en & sreg_c_wr_en;
|
470 |
|
|
|
471 |
|
|
|
472 |
|
|
-- INSTRUCTION FETCH
|
473 |
|
|
instruction_reg_ena <= '1'; -- FOR TEST
|
474 |
|
|
|
475 |
|
|
instruction_fetch:process(cp2,ireset)
|
476 |
|
|
begin
|
477 |
|
|
if ireset='0' then -- RESET
|
478 |
|
|
instruction_reg <= (others => '0');
|
479 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
480 |
|
|
if (cp2en='1') then -- Clock enable
|
481 |
|
|
if instruction_reg_ena='1' then
|
482 |
|
|
instruction_reg <= inst;
|
483 |
|
|
end if;
|
484 |
|
|
end if;
|
485 |
|
|
end if;
|
486 |
|
|
end process;
|
487 |
|
|
|
488 |
|
|
-- TWO WORDS INSTRUCTION DETECTOR (CONNECTED DIRECTLY TO THE INSTRUCTION REGISTER)
|
489 |
|
|
two_word_inst <= '1' when
|
490 |
|
|
((instruction_reg(15 downto 9)&instruction_reg(3 downto 1)="1001010111") or -- CALL
|
491 |
|
|
(instruction_reg(15 downto 9)&instruction_reg(3 downto 1)="1001010110")) or -- JMP
|
492 |
|
|
(instruction_reg(15 downto 9)&instruction_reg(3 downto 0) = "10010000000") or -- LDS
|
493 |
|
|
(instruction_reg(15 downto 9)&instruction_reg(3 downto 0) = "10010010000") -- STS
|
494 |
|
|
else '0'; -- TO DETECT CALL/JMP/LDS/STS INSTRUCTIONS FOR SBRS/SBRC/SBIS/SBIC/CPSE
|
495 |
|
|
|
496 |
|
|
|
497 |
|
|
|
498 |
|
|
-- DATA EXTRACTOR (CONNECTED DIRECTLY TO THE INSTRUCTION REGISTER)
|
499 |
|
|
dex_dat8_immed <= instruction_reg(11 downto 8) & instruction_reg(3 downto 0);
|
500 |
|
|
dex_dat6_immed <= instruction_reg(7 downto 6) & instruction_reg(3 downto 0);
|
501 |
|
|
dex_adr12mem_s <= instruction_reg(11 downto 0);
|
502 |
|
|
dex_adr6port <= instruction_reg(10 downto 9) & instruction_reg(3 downto 0);
|
503 |
|
|
dex_adr5port <= instruction_reg(7 downto 3);
|
504 |
|
|
dex_adr_disp <= instruction_reg(13) & instruction_reg(11 downto 10) & instruction_reg(2 downto 0);
|
505 |
|
|
dex_condition <= instruction_reg(2 downto 0);
|
506 |
|
|
dex_bitop_bitnum <= instruction_reg(2 downto 0); -- NUMBER(POSITION) OF TESTING BIT IN SBRC/SBRS/SBIC/SBIS INSTRUCTION
|
507 |
|
|
dex_bitnum_sreg <= instruction_reg(6 downto 4);
|
508 |
|
|
dex_adrreg_r <= instruction_reg(9) & instruction_reg(3 downto 0);
|
509 |
|
|
dex_adrreg_d <= instruction_reg(8 downto 4);
|
510 |
|
|
dex_brxx_offset <= instruction_reg(9 downto 3); -- OFFSET FOR BRBC/BRBS
|
511 |
|
|
dex_adiw_sbiw_reg_adr <= instruction_reg(5 downto 4); -- ADDRESS OF THE LOW REGISTER FOR ADIW/SBIW INSTRUCTIONS
|
512 |
|
|
--dex_adrindreg <= instruction_reg(3 downto 2);
|
513 |
|
|
|
514 |
|
|
-- LATCH Rd ADDDRESS FOR LDS/STS/POP INSTRUCTIONS
|
515 |
|
|
latcht_rd_adr:process(cp2,ireset)
|
516 |
|
|
begin
|
517 |
|
|
if ireset ='0' then
|
518 |
|
|
dex_adrreg_d_latched <= (others => '0');
|
519 |
|
|
elsif (cp2='1' and cp2'event) then
|
520 |
|
|
if (cp2en='1') then -- Clock enable
|
521 |
|
|
if ((idc_ld_x or idc_ld_y or idc_ldd_y or idc_ld_z or idc_ldd_z) or idc_sts or
|
522 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)or idc_lds or
|
523 |
|
|
idc_pop)='1' then
|
524 |
|
|
dex_adrreg_d_latched <= dex_adrreg_d;
|
525 |
|
|
end if;
|
526 |
|
|
end if;
|
527 |
|
|
end if;
|
528 |
|
|
end process;
|
529 |
|
|
-- +++++++++++++++++++++++++++++++++++++++++++++++++
|
530 |
|
|
|
531 |
|
|
|
532 |
|
|
-- R24:R25/R26:R27/R28:R29/R30:R31 ADIW/SBIW ADDRESS CONTROL LOGIC
|
533 |
|
|
adiw_sbiw_encoder_out <= "11"&dex_adiw_sbiw_reg_adr&'0';
|
534 |
|
|
|
535 |
|
|
adiw_sbiw_high_reg_adr:process(cp2,ireset)
|
536 |
|
|
begin
|
537 |
|
|
if ireset ='0' then
|
538 |
|
|
adiw_sbiw_encoder_mux_out <= (others=>'0');
|
539 |
|
|
elsif(cp2='1' and cp2'event) then
|
540 |
|
|
if (cp2en='1') then -- Clock enable
|
541 |
|
|
adiw_sbiw_encoder_mux_out <= adiw_sbiw_encoder_out +1;
|
542 |
|
|
end if;
|
543 |
|
|
end if;
|
544 |
|
|
end process;
|
545 |
|
|
|
546 |
|
|
-- ##########################
|
547 |
|
|
|
548 |
|
|
-- NOP INSERTION
|
549 |
|
|
|
550 |
|
|
--instruction_code_reg <= instruction_reg when nop_insert_st='0' else (others => '0');
|
551 |
|
|
instruction_code_reg <= (others => '0') when (nop_insert_st='1') else -- NOP
|
552 |
|
|
instruction_reg; -- Instruction
|
553 |
|
|
|
554 |
|
|
|
555 |
|
|
nop_insert_st <= adiw_st or sbiw_st or cbi_st or sbi_st or rjmp_st or ijmp_st or pop_st or push_st or
|
556 |
|
|
brxx_st or ld_st or st_st or ncall_st0 or nirq_st0 or nret_st0 or nreti_st0 or nlpm_st0 or njmp_st0 or
|
557 |
|
|
nrcall_st0 or nicall_st0 or sts_st or lds_st or nskip_inst_st0;
|
558 |
|
|
|
559 |
|
|
|
560 |
|
|
-- INSTRUCTION DECODER (CONNECTED AFTER NOP INSERTION LOGIC)
|
561 |
|
|
|
562 |
|
|
idc_adc <= '1' when instruction_code_reg(15 downto 10) = "000111" else '0'; -- 000111XXXXXXXXXX
|
563 |
|
|
idc_add <= '1' when instruction_code_reg(15 downto 10) = "000011" else '0'; -- 000011XXXXXXXXXX
|
564 |
|
|
|
565 |
|
|
idc_adiw <= '1' when instruction_code_reg(15 downto 8) = "10010110" else '0'; -- 10010110XXXXXXXX
|
566 |
|
|
|
567 |
|
|
idc_and <= '1' when instruction_code_reg(15 downto 10) = "001000" else '0'; -- 001000XXXXXXXXXX
|
568 |
|
|
idc_andi <= '1' when instruction_code_reg(15 downto 12) = "0111" else '0'; -- 0111XXXXXXXXXXXX
|
569 |
|
|
|
570 |
|
|
idc_asr <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010100101" else '0'; -- 1001010XXXXX0101
|
571 |
|
|
|
572 |
|
|
idc_bclr <= '1' when instruction_code_reg(15 downto 7)&instruction_code_reg(3 downto 0) = "1001010011000" else '0'; -- 100101001XXX1000
|
573 |
|
|
|
574 |
|
|
idc_bld <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3) = "11111000" else '0'; -- 1111100XXXXX0XXX
|
575 |
|
|
|
576 |
|
|
idc_brbc <= '1' when instruction_code_reg(15 downto 10) = "111101" else '0'; -- 111101XXXXXXXXXX
|
577 |
|
|
idc_brbs <= '1' when instruction_code_reg(15 downto 10) = "111100" else '0'; -- 111100XXXXXXXXXX
|
578 |
|
|
|
579 |
|
|
idc_bset <= '1' when instruction_code_reg(15 downto 7)&instruction_code_reg(3 downto 0) = "1001010001000" else '0'; -- 100101000XXX1000
|
580 |
|
|
|
581 |
|
|
idc_bst <= '1' when instruction_code_reg(15 downto 9) = "1111101" else '0'; -- 1111101XXXXXXXXX
|
582 |
|
|
|
583 |
|
|
idc_call <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 1) = "1001010111" else '0'; -- 1001010XXXXX111X
|
584 |
|
|
|
585 |
|
|
idc_cbi <= '1' when instruction_code_reg(15 downto 8) = "10011000" else '0'; -- 10011000XXXXXXXX
|
586 |
|
|
|
587 |
|
|
idc_com <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010100000" else '0'; -- 1001010XXXXX0000
|
588 |
|
|
|
589 |
|
|
idc_cp <= '1' when instruction_code_reg(15 downto 10) = "000101" else '0'; -- 000101XXXXXXXXXX
|
590 |
|
|
|
591 |
|
|
idc_cpc <= '1' when instruction_code_reg(15 downto 10) = "000001" else '0'; -- 000001XXXXXXXXXX
|
592 |
|
|
|
593 |
|
|
idc_cpi <= '1' when instruction_code_reg(15 downto 12) = "0011" else '0'; -- 0011XXXXXXXXXXXX
|
594 |
|
|
|
595 |
|
|
idc_cpse <= '1' when instruction_code_reg(15 downto 10) = "000100" else '0'; -- 000100XXXXXXXXXX
|
596 |
|
|
|
597 |
|
|
idc_dec <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010101010" else '0'; -- 1001010XXXXX1010
|
598 |
|
|
|
599 |
|
|
idc_elpm <= '1' when instruction_code_reg = "1001010111011000" else '0'; -- 1001010111011000
|
600 |
|
|
|
601 |
|
|
idc_eor <= '1' when instruction_code_reg(15 downto 10) = "001001" else '0'; -- 001001XXXXXXXXXX
|
602 |
|
|
|
603 |
|
|
idc_icall<= '1' when instruction_code_reg(15 downto 8)&instruction_code_reg(3 downto 0) = "100101011001" else '0'; -- 10010101XXXX1001
|
604 |
|
|
|
605 |
|
|
idc_ijmp <= '1' when instruction_code_reg(15 downto 8)&instruction_code_reg(3 downto 0) = "100101001001" else '0'; -- 10010100XXXX1001
|
606 |
|
|
|
607 |
|
|
idc_in <= '1' when instruction_code_reg(15 downto 11) = "10110" else '0'; -- 10110XXXXXXXXXXX
|
608 |
|
|
|
609 |
|
|
idc_inc <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010100011" else '0'; -- 1001010XXXXX0011
|
610 |
|
|
|
611 |
|
|
idc_jmp <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 1) = "1001010110" else '0'; -- 1001010XXXXX110X
|
612 |
|
|
|
613 |
|
|
|
614 |
|
|
-- LD,LDD
|
615 |
|
|
idc_ld_x <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010001100" or
|
616 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010001101" or
|
617 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010001110" else '0';
|
618 |
|
|
|
619 |
|
|
idc_ld_y <= '1' when (instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010001001" or
|
620 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010001010") else '0';
|
621 |
|
|
|
622 |
|
|
idc_ldd_y<= '1' when instruction_code_reg(15 downto 14)&instruction_code_reg(12)&instruction_code_reg(9)&instruction_code_reg(3) = "10001" else '0'; -- 10X0XX0XXXXX1XXX
|
623 |
|
|
|
624 |
|
|
idc_ld_z <= '1' when (instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010000001" or
|
625 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010000010") else '0';
|
626 |
|
|
|
627 |
|
|
idc_ldd_z<= '1' when instruction_code_reg(15 downto 14)&instruction_code_reg(12)&instruction_code_reg(9)&instruction_code_reg(3) = "10000" else '0'; -- 10X0XX0XXXXX0XXX
|
628 |
|
|
-- ######
|
629 |
|
|
|
630 |
|
|
|
631 |
|
|
idc_ldi <= '1' when instruction_code_reg(15 downto 12) = "1110" else '0'; -- 1110XXXXXXXXXXXX
|
632 |
|
|
|
633 |
|
|
idc_lds <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010000000" else '0'; -- 1001000XXXXX0000
|
634 |
|
|
|
635 |
|
|
idc_lpm <= '1' when instruction_code_reg = "1001010111001000" else '0'; -- 1001010111001000
|
636 |
|
|
|
637 |
|
|
idc_lsr <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010100110" else '0'; -- 1001010XXXXX0110
|
638 |
|
|
|
639 |
|
|
idc_mov <= '1' when instruction_code_reg(15 downto 10) = "001011" else '0'; -- 001011XXXXXXXXXX
|
640 |
|
|
|
641 |
|
|
idc_mul <= '1' when instruction_code_reg(15 downto 10) = "100111" else '0'; -- 100111XXXXXXXXXX
|
642 |
|
|
|
643 |
|
|
idc_neg <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010100001" else '0'; -- 1001010XXXXX0001
|
644 |
|
|
|
645 |
|
|
idc_nop <= '1' when instruction_code_reg = "0000000000000000" else '0'; -- 0000000000000000
|
646 |
|
|
|
647 |
|
|
idc_or <= '1' when instruction_code_reg(15 downto 10) = "001010" else '0'; -- 001010XXXXXXXXXX
|
648 |
|
|
|
649 |
|
|
idc_ori <= '1' when instruction_code_reg(15 downto 12) = "0110" else '0'; -- 0110XXXXXXXXXXXX
|
650 |
|
|
|
651 |
|
|
idc_out <= '1' when instruction_code_reg(15 downto 11) = "10111" else '0'; -- 10111XXXXXXXXXXX
|
652 |
|
|
|
653 |
|
|
idc_pop <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010001111" else '0'; -- 1001000XXXXX1111
|
654 |
|
|
|
655 |
|
|
idc_push<= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010011111" else '0'; -- 1001001XXXXX1111
|
656 |
|
|
|
657 |
|
|
idc_rcall<= '1' when instruction_code_reg(15 downto 12) = "1101" else '0'; -- 1101XXXXXXXXXXXX
|
658 |
|
|
|
659 |
|
|
idc_ret <= '1' when instruction_code_reg(15 downto 7)&instruction_code_reg(4 downto 0) = "10010101001000" else '0'; -- 100101010XX01000
|
660 |
|
|
|
661 |
|
|
idc_reti <= '1' when instruction_code_reg(15 downto 7)&instruction_code_reg(4 downto 0) = "10010101011000" else '0'; -- 100101010XX11000
|
662 |
|
|
|
663 |
|
|
idc_rjmp <= '1' when instruction_code_reg(15 downto 12) = "1100" else '0'; -- 1100XXXXXXXXXXXX
|
664 |
|
|
|
665 |
|
|
idc_ror <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010100111" else '0'; -- 1001010XXXXX0111
|
666 |
|
|
|
667 |
|
|
idc_sbc <= '1' when instruction_code_reg(15 downto 10) = "000010" else '0'; -- 000010XXXXXXXXXX
|
668 |
|
|
|
669 |
|
|
idc_sbci <= '1' when instruction_code_reg(15 downto 12) = "0100" else '0'; -- 0100XXXXXXXXXXXX
|
670 |
|
|
|
671 |
|
|
idc_sbi <= '1' when instruction_code_reg(15 downto 8) = "10011010" else '0'; -- 10011010XXXXXXXX
|
672 |
|
|
|
673 |
|
|
idc_sbic <= '1' when instruction_code_reg(15 downto 8) = "10011001" else '0'; -- 10011001XXXXXXXX
|
674 |
|
|
|
675 |
|
|
idc_sbis <= '1' when instruction_code_reg(15 downto 8) = "10011011" else '0'; -- 10011011XXXXXXXX
|
676 |
|
|
|
677 |
|
|
idc_sbiw <= '1' when instruction_code_reg(15 downto 8) = "10010111" else '0'; -- 10010111XXXXXXXX
|
678 |
|
|
|
679 |
|
|
idc_sbrc <= '1' when instruction_code_reg(15 downto 9) = "1111110" else '0'; -- 1111110XXXXXXXXX
|
680 |
|
|
|
681 |
|
|
idc_sbrs <= '1' when instruction_code_reg(15 downto 9) = "1111111" else '0'; -- 1111111XXXXXXXXX
|
682 |
|
|
|
683 |
|
|
idc_sleep<= '1' when instruction_code_reg(15 downto 5)&instruction_code_reg(3 downto 0) = "100101011001000" else '0'; -- 10010101100X1000
|
684 |
|
|
|
685 |
|
|
|
686 |
|
|
-- ST,STD
|
687 |
|
|
idc_st_x <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010011100" or
|
688 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010011101" or
|
689 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010011110" else '0';
|
690 |
|
|
|
691 |
|
|
idc_st_y <= '1' when (instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010011001" or
|
692 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010011010") else '0';
|
693 |
|
|
|
694 |
|
|
idc_std_y<= '1' when instruction_code_reg(15 downto 14)&instruction_code_reg(12)&instruction_code_reg(9)&instruction_code_reg(3) = "10011" else '0'; -- 10X0XX1XXXXX1XXX
|
695 |
|
|
|
696 |
|
|
idc_st_z <= '1' when (instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010010001" or
|
697 |
|
|
instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0)="10010010010") else '0';
|
698 |
|
|
|
699 |
|
|
idc_std_z<= '1' when instruction_code_reg(15 downto 14)&instruction_code_reg(12)&instruction_code_reg(9)&instruction_code_reg(3) = "10010" else '0'; -- 10X0XX1XXXXX0XXX
|
700 |
|
|
-- ######
|
701 |
|
|
|
702 |
|
|
idc_sts <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010010000" else '0'; -- 1001001XXXXX0000
|
703 |
|
|
|
704 |
|
|
idc_sub <= '1' when instruction_code_reg(15 downto 10) = "000110" else '0'; -- 000110XXXXXXXXXX
|
705 |
|
|
|
706 |
|
|
idc_subi <= '1' when instruction_code_reg(15 downto 12) = "0101" else '0'; -- 0101XXXXXXXXXXXX
|
707 |
|
|
|
708 |
|
|
idc_swap <= '1' when instruction_code_reg(15 downto 9)&instruction_code_reg(3 downto 0) = "10010100010" else '0'; -- 1001010XXXXX0010
|
709 |
|
|
|
710 |
|
|
idc_wdr <= '1' when instruction_code_reg(15 downto 5)&instruction_code_reg(3 downto 0) = "100101011011000" else '0'; -- 10010101101X1000
|
711 |
|
|
|
712 |
|
|
-- ADDITIONAL SIGNALS
|
713 |
|
|
idc_psinc <= '1' when (instruction_code_reg(1 downto 0) = "01" and
|
714 |
|
|
(idc_st_x or idc_st_y or idc_st_z or idc_ld_x or idc_ld_y or idc_ld_z)='1') else '0'; -- POST INCREMENT FOR LD/ST INSTRUCTIONS
|
715 |
|
|
|
716 |
|
|
idc_prdec <= '1' when (instruction_code_reg(1 downto 0) = "10" and
|
717 |
|
|
(idc_st_x or idc_st_y or idc_st_z or idc_ld_x or idc_ld_y or idc_ld_z)='1') else '0'; -- PRE DECREMENT FOR LD/ST INSTRUCTIONS
|
718 |
|
|
|
719 |
|
|
|
720 |
|
|
-- ##########################################################################################################
|
721 |
|
|
|
722 |
|
|
-- WRITE ENABLE SIGNALS FOR ramadr_reg
|
723 |
|
|
ramadr_reg_en <= idc_ld_x or idc_ld_y or idc_ldd_y or idc_ld_z or idc_ldd_z or idc_lds or -- LD/LDD/LDS(two cycle execution)
|
724 |
|
|
idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z or idc_sts or -- ST/STS/STS(two cycle execution)
|
725 |
|
|
idc_push or idc_pop or
|
726 |
|
|
idc_rcall or (rcall_st1 and not cpuwait) or idc_icall or (icall_st1 and not cpuwait) or -- RCALL/ICALL
|
727 |
|
|
call_st1 or (call_st2 and not cpuwait) or irq_st1 or (irq_st2 and not cpuwait) or -- CALL/IRQ
|
728 |
|
|
idc_ret or (ret_st1 and not cpuwait ) or idc_reti or (reti_st1 and not cpuwait); -- RET/RETI -- ??
|
729 |
|
|
|
730 |
|
|
|
731 |
|
|
-- RAMADR MUX
|
732 |
|
|
ramadr_reg_in <= sph_out&spl_out when
|
733 |
|
|
(idc_rcall or (rcall_st1 and not cpuwait)or idc_icall or (icall_st1 and not cpuwait)or -- RCALL/ICALL
|
734 |
|
|
call_st1 or (call_st2 and not cpuwait) or irq_st1 or (irq_st2 and not cpuwait) or -- CALL/IRQ
|
735 |
|
|
idc_push )='1' else -- PUSH
|
736 |
|
|
(sph_out&spl_out)+1 when (idc_ret or (ret_st1 and not cpuwait) or idc_reti or (reti_st1 and not cpuwait) or idc_pop)='1' else -- RET/RETI/POP
|
737 |
|
|
inst when (idc_lds or idc_sts) ='1' else -- LDS/STS (two cycle execution)
|
738 |
|
|
reg_h_out when (idc_ld_x or idc_ld_y or idc_ld_z or idc_st_x or idc_st_y or idc_st_z)='1' else -- LD/ST
|
739 |
|
|
(reg_h_out + ("000000000"&dex_adr_disp)); -- LDD/STD
|
740 |
|
|
|
741 |
|
|
|
742 |
|
|
-- ADDRESS REGISTER
|
743 |
|
|
ramadr_reg:process(cp2,ireset)
|
744 |
|
|
begin
|
745 |
|
|
if ireset='0' then
|
746 |
|
|
ramadr_int <= (others => '0');
|
747 |
|
|
elsif(cp2='1' and cp2'event) then
|
748 |
|
|
if (cp2en='1') then -- Clock enable
|
749 |
|
|
if (ramadr_reg_en='1') then
|
750 |
|
|
ramadr_int <= ramadr_reg_in;
|
751 |
|
|
end if;
|
752 |
|
|
end if;
|
753 |
|
|
end if;
|
754 |
|
|
end process;
|
755 |
|
|
|
756 |
|
|
ramadr <= ramadr_int;
|
757 |
|
|
|
758 |
|
|
-- GENERAL PURPOSE REGISTERS ADDRESSING FLAG FOR ST/STD/STS INSTRUCTIONS
|
759 |
|
|
gp_reg_adr:process(cp2,ireset)
|
760 |
|
|
begin
|
761 |
|
|
if ireset='0' then
|
762 |
|
|
reg_file_adr_space <='0';
|
763 |
|
|
elsif(cp2='1' and cp2'event) then
|
764 |
|
|
if (cp2en='1') then -- Clock enable
|
765 |
|
|
if (ramadr_reg_en='1') then
|
766 |
|
|
if (ramadr_reg_in(15 downto 5)=const_ram_to_reg) then
|
767 |
|
|
reg_file_adr_space <= '1'; -- ADRESS RANGE 0x0000-0x001F -> REGISTERS (R0-R31)
|
768 |
|
|
else
|
769 |
|
|
reg_file_adr_space <= '0';
|
770 |
|
|
end if;
|
771 |
|
|
end if;
|
772 |
|
|
end if;
|
773 |
|
|
end if;
|
774 |
|
|
end process;
|
775 |
|
|
|
776 |
|
|
-- I/O REGISTERS ADDRESSING FLAG FOR ST/STD/STS INSTRUCTIONS
|
777 |
|
|
io_reg_adr:process(cp2,ireset)
|
778 |
|
|
begin
|
779 |
|
|
if ireset='0' then io_file_adr_space<='0';
|
780 |
|
|
elsif(cp2='1' and cp2'event) then
|
781 |
|
|
if (cp2en='1') then -- Clock enable
|
782 |
|
|
if (ramadr_reg_en='1') then
|
783 |
|
|
if (ramadr_reg_in(15 downto 5)=const_ram_to_io_a or ramadr_reg_in(15 downto 5)=const_ram_to_io_b) then
|
784 |
|
|
io_file_adr_space <= '1'; -- ADRESS RANGE 0x0020-0x005F -> I/O PORTS (0x00-0x3F)
|
785 |
|
|
else
|
786 |
|
|
io_file_adr_space <= '0';
|
787 |
|
|
end if;
|
788 |
|
|
end if;
|
789 |
|
|
end if;
|
790 |
|
|
end if;
|
791 |
|
|
end process;
|
792 |
|
|
|
793 |
|
|
|
794 |
|
|
|
795 |
|
|
-- ##########################################################################################################
|
796 |
|
|
|
797 |
|
|
|
798 |
|
|
-- REGRE/REGWE LOGIC (5 BIT ADDSRESS BUS (INTERNAL ONLY) 32 LOCATIONS (R0-R31))
|
799 |
|
|
|
800 |
|
|
-- WRITE ENABLE FOR Rd REGISTERS
|
801 |
|
|
alu_reg_wr <= idc_adc or idc_add or idc_adiw or adiw_st or idc_sub or idc_subi or idc_sbc or idc_sbci or
|
802 |
|
|
idc_sbiw or sbiw_st or idc_and or idc_andi or idc_or or idc_ori or idc_eor or idc_com or
|
803 |
|
|
idc_neg or idc_inc or idc_dec or idc_lsr or idc_ror or idc_asr or idc_swap;
|
804 |
|
|
|
805 |
|
|
|
806 |
|
|
reg_rd_wr <= idc_in or alu_reg_wr or idc_bld or -- ALU INSTRUCTIONS + IN/BLD INSRTRUCTION
|
807 |
|
|
(pop_st or ld_st or lds_st)or -- POP/LD/LDD/LDS INSTRUCTIONS
|
808 |
|
|
((st_st or sts_st) and reg_file_adr_space)or -- ST/STD/STS INSTRUCTION
|
809 |
|
|
lpm_st2 or idc_ldi or idc_mov; -- LPM/LDI/MOV INSTRUCTION
|
810 |
|
|
|
811 |
|
|
|
812 |
|
|
reg_rd_adr <= '1'&dex_adrreg_d(3 downto 0) when (idc_subi or idc_sbci or idc_andi or idc_ori or idc_cpi or idc_ldi)='1' else
|
813 |
|
|
"00000" when lpm_st2='1' else
|
814 |
|
|
adiw_sbiw_encoder_out when (idc_adiw or idc_sbiw)='1' else
|
815 |
|
|
adiw_sbiw_encoder_mux_out when (adiw_st or sbiw_st)='1' else
|
816 |
|
|
dex_adrreg_d_latched when (((st_st or sts_st) and not reg_file_adr_space) or ld_st or lds_st or pop_st)='1' else
|
817 |
|
|
ramadr_int(4 downto 0) when ((st_st or sts_st) and reg_file_adr_space)='1'else --!!??
|
818 |
|
|
dex_adrreg_d;
|
819 |
|
|
|
820 |
|
|
reg_rd_adr_int <= '1'&dex_adrreg_d(3 downto 0) when (idc_subi or idc_sbci or idc_andi or idc_ori or idc_cpi or idc_ldi)='1' else
|
821 |
|
|
"00000" when lpm_st2='1' else
|
822 |
|
|
adiw_sbiw_encoder_out when (idc_adiw or idc_sbiw)='1' else
|
823 |
|
|
adiw_sbiw_encoder_mux_out when (adiw_st or sbiw_st)='1' else
|
824 |
|
|
dex_adrreg_d_latched when (((st_st or sts_st) and not reg_file_adr_space) or ld_st or lds_st or pop_st)='1' else
|
825 |
|
|
ramadr_int(4 downto 0) when ((st_st or sts_st) and reg_file_adr_space)='1'else --!!??
|
826 |
|
|
dex_adrreg_d;
|
827 |
|
|
|
828 |
|
|
reg_rr_adr <= ramadr_int(4 downto 0) when ((ld_st or lds_st) and reg_file_adr_space)='1'else --!!??
|
829 |
|
|
dex_adrreg_d_latched when ((st_st or sts_st) and reg_file_adr_space)='1'else --!!??
|
830 |
|
|
dex_adrreg_r;
|
831 |
|
|
|
832 |
|
|
-- MULTIPLEXER FOR REGISTER FILE Rd INPUT
|
833 |
|
|
reg_rd_in <= dbusin when (idc_in or ((lds_st or ld_st)and not reg_file_adr_space) or pop_st)='1' else -- FROM INPUT DATA BUS
|
834 |
|
|
reg_rr_out when ((lds_st or ld_st) and reg_file_adr_space)='1' else
|
835 |
|
|
gp_reg_tmp when ((st_st or sts_st) and reg_file_adr_space)='1' else -- ST/STD/STS & ADDRESS FROM 0 TO 31 (REGISTER FILE)
|
836 |
|
|
bld_op_out when (idc_bld='1')else -- FROM BIT PROCESSOR BLD COMMAND
|
837 |
|
|
reg_rr_out when (idc_mov='1')else -- FOR MOV INSTRUCTION
|
838 |
|
|
instruction_reg(15 downto 8) when (lpm_st2='1' and reg_z_out(0)='1') else -- LPM/ELPM
|
839 |
|
|
instruction_reg(7 downto 0) when (lpm_st2='1' and reg_z_out(0)='0') else -- LPM/ELPM
|
840 |
|
|
dex_dat8_immed when idc_ldi='1' else
|
841 |
|
|
alu_data_out; -- FROM ALU DATA OUT
|
842 |
|
|
|
843 |
|
|
-- IORE/IOWE LOGIC (6 BIT ADDRESS adr[5..0] FOR I/O PORTS(64 LOCATIONS))
|
844 |
|
|
iore_int <= idc_in or idc_sbi or idc_cbi or idc_sbic or idc_sbis or ((ld_st or lds_st) and io_file_adr_space); -- IN/SBI/CBI
|
845 |
|
|
iowe_int <= '1' when ((idc_out or sbi_st or cbi_st) or
|
846 |
|
|
((st_st or sts_st) and io_file_adr_space))='1' else '0'; -- OUT/SBI/CBI + !! ST/STS/STD
|
847 |
|
|
|
848 |
|
|
|
849 |
|
|
-- adr[5..0] BUS MULTIPLEXER
|
850 |
|
|
adr_int <= dex_adr6port when (idc_in or idc_out) = '1' else -- IN/OUT INSTRUCTIONS
|
851 |
|
|
'0'&dex_adr5port when (idc_cbi or idc_sbi or idc_sbic or idc_sbis) ='1' else -- CBI/SBI (READ PHASE) + SBIS/SBIC
|
852 |
|
|
'0'&cbi_sbi_io_adr_tmp when (cbi_st or sbi_st)='1' else -- CBI/SBI (WRITE PHASE)
|
853 |
|
|
ramadr_int(6)&ramadr_int(4 downto 0); -- LD/LDS/LDD/ST/STS/STD
|
854 |
|
|
|
855 |
|
|
-- ramre LOGIC (16 BIT ADDRESS ramadr[15..0] FOR DATA RAM (64*1024-64-32 LOCATIONS))
|
856 |
|
|
--ramre_int <= not(reg_file_adr_space or io_file_adr_space) and
|
857 |
|
|
-- (ld_st or lds_st2 or pop_st or -- LD/LDD/LDS/POP/
|
858 |
|
|
-- ret_st1 or ret_st2 or reti_st1 or reti_st2); -- RET/RETI
|
859 |
|
|
|
860 |
|
|
DataMemoryRead:process(cp2,ireset)
|
861 |
|
|
begin
|
862 |
|
|
if ireset='0' then -- Reset
|
863 |
|
|
ramre_int <= '0';
|
864 |
|
|
elsif (cp2='1' and cp2'event) then -- Clock
|
865 |
|
|
if (cp2en='1') then -- Clock enable
|
866 |
|
|
case ramre_int is
|
867 |
|
|
when '0' =>
|
868 |
|
|
if(ramadr_reg_in(15 downto 5)/=const_ram_to_io_a and
|
869 |
|
|
ramadr_reg_in(15 downto 5)/=const_ram_to_io_b and
|
870 |
|
|
ramadr_reg_in(15 downto 5)/=const_ram_to_reg and
|
871 |
|
|
(idc_ld_x or idc_ld_y or idc_ldd_y or idc_ld_z or idc_ldd_z or -- LD/LDD instruction
|
872 |
|
|
idc_lds or -- LDS instruction(two cycle execution)
|
873 |
|
|
idc_pop or -- POP instruction
|
874 |
|
|
idc_ret or -- RET instruction
|
875 |
|
|
idc_reti)='1') -- RETI instruction
|
876 |
|
|
then ramre_int <='1';
|
877 |
|
|
end if;
|
878 |
|
|
when '1' =>
|
879 |
|
|
if ((ld_st or lds_st or pop_st or ret_st2 or reti_st2)and not cpuwait)='1' then
|
880 |
|
|
ramre_int <='0';
|
881 |
|
|
end if;
|
882 |
|
|
when others => null;
|
883 |
|
|
end case;
|
884 |
|
|
end if;
|
885 |
|
|
end if;
|
886 |
|
|
end process;
|
887 |
|
|
|
888 |
|
|
-- ramwe LOGIC (16 BIT ADDRESS ramadr[15..0] FOR DATA RAM (64*1024-64-32 LOCATIONS))
|
889 |
|
|
--ramwe_int <= not(reg_file_adr_space or io_file_adr_space) and
|
890 |
|
|
-- (st_st or sts_st2 or push_st or rcall_st1 or rcall_st2 or -- ST/STD/STS/PUSH/RCALL
|
891 |
|
|
-- icall_st1 or icall_st2 or -- ICALL
|
892 |
|
|
-- call_st2 or call_st3 or -- CALL
|
893 |
|
|
-- irq_st2 or irq_st3); -- INTERRUPT
|
894 |
|
|
|
895 |
|
|
DataMemoryWrite:process(cp2,ireset)
|
896 |
|
|
begin
|
897 |
|
|
if ireset='0' then -- Reset
|
898 |
|
|
ramwe_int <= '0';
|
899 |
|
|
elsif (cp2='1' and cp2'event) then -- Clock
|
900 |
|
|
if (cp2en='1') then -- Clock enable
|
901 |
|
|
case ramwe_int is
|
902 |
|
|
when '0' =>
|
903 |
|
|
if(ramadr_reg_in(15 downto 5)/=const_ram_to_io_a and
|
904 |
|
|
ramadr_reg_in(15 downto 5)/=const_ram_to_io_b and
|
905 |
|
|
ramadr_reg_in(15 downto 5)/=const_ram_to_reg and
|
906 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z or -- ST/STD instruction
|
907 |
|
|
idc_sts or -- STS instruction (two cycle execution)
|
908 |
|
|
idc_push or -- PUSH instruction
|
909 |
|
|
idc_rcall or -- RCALL instruction
|
910 |
|
|
idc_icall or -- ICALL instruction
|
911 |
|
|
call_st1 or -- CALL instruction
|
912 |
|
|
irq_st1)='1') -- Interrupt
|
913 |
|
|
then ramwe_int <='1';
|
914 |
|
|
end if;
|
915 |
|
|
when '1' =>
|
916 |
|
|
if ((st_st or sts_st or push_st or rcall_st2 or
|
917 |
|
|
icall_st2 or call_st3 or irq_st3)and not cpuwait)='1' then ramwe_int <='0';
|
918 |
|
|
end if;
|
919 |
|
|
when others => null;
|
920 |
|
|
end case;
|
921 |
|
|
end if;
|
922 |
|
|
end if;
|
923 |
|
|
end process;
|
924 |
|
|
|
925 |
|
|
-- DBUSOUT MULTIPLEXER
|
926 |
|
|
--dbusout_mux_logic: for i in dbusout_int'range generate
|
927 |
|
|
--dbusout_int(i)<= (reg_rd_out(i) and (idc_push or idc_sts or
|
928 |
|
|
-- (idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
929 |
|
|
-- (gp_reg_tmp(i) and (st_st or sts_st))or -- NEW
|
930 |
|
|
-- (bitpr_io_out(i) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
931 |
|
|
-- (program_counter(i) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC (program_counter_high_fr(i) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
932 |
|
|
-- (pc_for_interrupt(i) and irq_st1) or
|
933 |
|
|
-- (pc_for_interrupt(8) and irq_st2) or
|
934 |
|
|
-- (reg_rd_out(i) and idc_out); -- OUT
|
935 |
|
|
--end generate;
|
936 |
|
|
|
937 |
|
|
dbusout_int(0)<= (reg_rd_out(0) and (idc_push or idc_sts or
|
938 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
939 |
|
|
(gp_reg_tmp(0) and (st_st or sts_st))or -- NEW
|
940 |
|
|
(bitpr_io_out(0) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
941 |
|
|
(program_counter(0) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
942 |
|
|
(program_counter_high_fr(0) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
943 |
|
|
(pc_for_interrupt(0) and irq_st1) or
|
944 |
|
|
(pc_for_interrupt(8) and irq_st2) or
|
945 |
|
|
(reg_rd_out(0) and idc_out); -- OUT
|
946 |
|
|
|
947 |
|
|
dbusout_int(1)<= (reg_rd_out(1) and (idc_push or idc_sts or
|
948 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
949 |
|
|
(gp_reg_tmp(1) and (st_st or sts_st))or -- NEW
|
950 |
|
|
(bitpr_io_out(1) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
951 |
|
|
(program_counter(1) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
952 |
|
|
(program_counter_high_fr(1) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
953 |
|
|
(pc_for_interrupt(1) and irq_st1) or
|
954 |
|
|
(pc_for_interrupt(9) and irq_st2) or
|
955 |
|
|
(reg_rd_out(1) and idc_out); -- OUT
|
956 |
|
|
|
957 |
|
|
dbusout_int(2)<= (reg_rd_out(2) and (idc_push or idc_sts or
|
958 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
959 |
|
|
(gp_reg_tmp(2) and (st_st or sts_st))or -- NEW
|
960 |
|
|
(bitpr_io_out(2) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
961 |
|
|
(program_counter(2) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
962 |
|
|
(program_counter_high_fr(2) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
963 |
|
|
(pc_for_interrupt(2) and irq_st1) or
|
964 |
|
|
(pc_for_interrupt(10) and irq_st2) or
|
965 |
|
|
(reg_rd_out(2) and idc_out); -- OUT
|
966 |
|
|
|
967 |
|
|
dbusout_int(3)<= (reg_rd_out(3) and (idc_push or idc_sts or
|
968 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
969 |
|
|
(gp_reg_tmp(3) and (st_st or sts_st))or -- NEW
|
970 |
|
|
(bitpr_io_out(3) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
971 |
|
|
(program_counter(3) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
972 |
|
|
(program_counter_high_fr(3) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
973 |
|
|
(pc_for_interrupt(3) and irq_st1) or
|
974 |
|
|
(pc_for_interrupt(11) and irq_st2) or
|
975 |
|
|
(reg_rd_out(3) and idc_out); -- OUT
|
976 |
|
|
|
977 |
|
|
dbusout_int(4)<= (reg_rd_out(4) and (idc_push or idc_sts or
|
978 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
979 |
|
|
(gp_reg_tmp(4) and (st_st or sts_st))or -- NEW
|
980 |
|
|
(bitpr_io_out(4) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
981 |
|
|
(program_counter(4) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
982 |
|
|
(program_counter_high_fr(4) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
983 |
|
|
(pc_for_interrupt(4) and irq_st1) or
|
984 |
|
|
(pc_for_interrupt(12) and irq_st2) or
|
985 |
|
|
(reg_rd_out(4) and idc_out); -- OUT
|
986 |
|
|
|
987 |
|
|
dbusout_int(5)<= (reg_rd_out(5) and (idc_push or idc_sts or
|
988 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
989 |
|
|
(gp_reg_tmp(5) and (st_st or sts_st))or -- NEW
|
990 |
|
|
(bitpr_io_out(5) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
991 |
|
|
(program_counter(5) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
992 |
|
|
(program_counter_high_fr(5) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
993 |
|
|
(pc_for_interrupt(5) and irq_st1) or
|
994 |
|
|
(pc_for_interrupt(13) and irq_st2) or
|
995 |
|
|
(reg_rd_out(5) and idc_out); -- OUT
|
996 |
|
|
|
997 |
|
|
dbusout_int(6)<= (reg_rd_out(6) and (idc_push or idc_sts or
|
998 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
999 |
|
|
(gp_reg_tmp(6) and (st_st or sts_st))or -- NEW
|
1000 |
|
|
(bitpr_io_out(6) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1001 |
|
|
(program_counter(6) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1002 |
|
|
(program_counter_high_fr(6) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1003 |
|
|
(pc_for_interrupt(6) and irq_st1) or
|
1004 |
|
|
(pc_for_interrupt(14) and irq_st2) or
|
1005 |
|
|
(reg_rd_out(6) and idc_out); -- OUT
|
1006 |
|
|
|
1007 |
|
|
dbusout_int(7)<= (reg_rd_out(7) and (idc_push or idc_sts or
|
1008 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1009 |
|
|
(gp_reg_tmp(7) and (st_st or sts_st))or -- NEW
|
1010 |
|
|
(bitpr_io_out(7) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1011 |
|
|
(program_counter(7) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1012 |
|
|
(program_counter_high_fr(7) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1013 |
|
|
(pc_for_interrupt(7) and irq_st1) or
|
1014 |
|
|
(pc_for_interrupt(15) and irq_st2) or
|
1015 |
|
|
(reg_rd_out(7) and idc_out); -- OUT
|
1016 |
|
|
|
1017 |
|
|
dbusout_int_route <= dbusout_int;
|
1018 |
|
|
|
1019 |
|
|
dbusout(0)<= (reg_rd_out_int(0) and (idc_push or idc_sts or
|
1020 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1021 |
|
|
(gp_reg_tmp(0) and (st_st or sts_st))or -- NEW
|
1022 |
|
|
(bitpr_io_out(0) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1023 |
|
|
(program_counter(0) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1024 |
|
|
(program_counter_high_fr(0) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1025 |
|
|
(pc_for_interrupt(0) and irq_st1) or
|
1026 |
|
|
(pc_for_interrupt(8) and irq_st2) or
|
1027 |
|
|
(reg_rd_out_int(0) and idc_out); -- OUT
|
1028 |
|
|
|
1029 |
|
|
dbusout(1)<= (reg_rd_out_int(1) and (idc_push or idc_sts or
|
1030 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1031 |
|
|
(gp_reg_tmp(1) and (st_st or sts_st))or -- NEW
|
1032 |
|
|
(bitpr_io_out(1) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1033 |
|
|
(program_counter(1) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1034 |
|
|
(program_counter_high_fr(1) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1035 |
|
|
(pc_for_interrupt(1) and irq_st1) or
|
1036 |
|
|
(pc_for_interrupt(9) and irq_st2) or
|
1037 |
|
|
(reg_rd_out_int(1) and idc_out); -- OUT
|
1038 |
|
|
|
1039 |
|
|
dbusout(2)<= (reg_rd_out_int(2) and (idc_push or idc_sts or
|
1040 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1041 |
|
|
(gp_reg_tmp(2) and (st_st or sts_st))or -- NEW
|
1042 |
|
|
(bitpr_io_out(2) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1043 |
|
|
(program_counter(2) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1044 |
|
|
(program_counter_high_fr(2) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1045 |
|
|
(pc_for_interrupt(2) and irq_st1) or
|
1046 |
|
|
(pc_for_interrupt(10) and irq_st2) or
|
1047 |
|
|
(reg_rd_out_int(2) and idc_out); -- OUT
|
1048 |
|
|
|
1049 |
|
|
dbusout(3)<= (reg_rd_out_int(3) and (idc_push or idc_sts or
|
1050 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1051 |
|
|
(gp_reg_tmp(3) and (st_st or sts_st))or -- NEW
|
1052 |
|
|
(bitpr_io_out(3) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1053 |
|
|
(program_counter(3) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1054 |
|
|
(program_counter_high_fr(3) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1055 |
|
|
(pc_for_interrupt(3) and irq_st1) or
|
1056 |
|
|
(pc_for_interrupt(11) and irq_st2) or
|
1057 |
|
|
(reg_rd_out_int(3) and idc_out); -- OUT
|
1058 |
|
|
|
1059 |
|
|
dbusout(4)<= (reg_rd_out_int(4) and (idc_push or idc_sts or
|
1060 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1061 |
|
|
(gp_reg_tmp(4) and (st_st or sts_st))or -- NEW
|
1062 |
|
|
(bitpr_io_out(4) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1063 |
|
|
(program_counter(4) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1064 |
|
|
(program_counter_high_fr(4) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1065 |
|
|
(pc_for_interrupt(4) and irq_st1) or
|
1066 |
|
|
(pc_for_interrupt(12) and irq_st2) or
|
1067 |
|
|
(reg_rd_out_int(4) and idc_out); -- OUT
|
1068 |
|
|
|
1069 |
|
|
dbusout(5)<= (reg_rd_out_int(5) and (idc_push or idc_sts or
|
1070 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1071 |
|
|
(gp_reg_tmp(5) and (st_st or sts_st))or -- NEW
|
1072 |
|
|
(bitpr_io_out(5) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1073 |
|
|
(program_counter(5) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1074 |
|
|
(program_counter_high_fr(5) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1075 |
|
|
(pc_for_interrupt(5) and irq_st1) or
|
1076 |
|
|
(pc_for_interrupt(13) and irq_st2) or
|
1077 |
|
|
(reg_rd_out_int(5) and idc_out); -- OUT
|
1078 |
|
|
|
1079 |
|
|
dbusout(6)<= (reg_rd_out_int(6) and (idc_push or idc_sts or
|
1080 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1081 |
|
|
(gp_reg_tmp(6) and (st_st or sts_st))or -- NEW
|
1082 |
|
|
(bitpr_io_out(6) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1083 |
|
|
(program_counter(6) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1084 |
|
|
(program_counter_high_fr(6) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1085 |
|
|
(pc_for_interrupt(6) and irq_st1) or
|
1086 |
|
|
(pc_for_interrupt(14) and irq_st2) or
|
1087 |
|
|
(reg_rd_out_int(6) and idc_out); -- OUT
|
1088 |
|
|
|
1089 |
|
|
dbusout(7)<= (reg_rd_out_int(7) and (idc_push or idc_sts or
|
1090 |
|
|
(idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)))or -- PUSH/ST/STD/STS INSTRUCTIONS
|
1091 |
|
|
(gp_reg_tmp(7) and (st_st or sts_st))or -- NEW
|
1092 |
|
|
(bitpr_io_out(7) and (cbi_st or sbi_st))or -- CBI/SBI INSTRUCTIONS
|
1093 |
|
|
(program_counter(7) and (idc_rcall or idc_icall or call_st1))or -- LOW PART OF PC
|
1094 |
|
|
(program_counter_high_fr(7) and (rcall_st1 or icall_st1 or call_st2))or -- HIGH PART OF PC
|
1095 |
|
|
(pc_for_interrupt(7) and irq_st1) or
|
1096 |
|
|
(pc_for_interrupt(15) and irq_st2) or
|
1097 |
|
|
(reg_rd_out_int(7) and idc_out); -- OUT
|
1098 |
|
|
|
1099 |
|
|
|
1100 |
|
|
-- ALU CONNECTION
|
1101 |
|
|
|
1102 |
|
|
-- ALU Rr INPUT MUX
|
1103 |
|
|
alu_data_r_in <= dex_dat8_immed when (idc_subi or idc_sbci or idc_andi or idc_ori or idc_cpi)='1' else
|
1104 |
|
|
"00"&dex_dat6_immed when (idc_adiw or idc_sbiw) ='1' else
|
1105 |
|
|
"00000000" when (adiw_st or sbiw_st) ='1' else
|
1106 |
|
|
reg_rr_out;
|
1107 |
|
|
|
1108 |
|
|
|
1109 |
|
|
-- gp_reg_tmp STORES TEMPREOARY THE VALUE OF SOURCE REGISTER DURING ST/STD/STS INSTRUCTION
|
1110 |
|
|
gp_registers_trig:process(cp2,ireset)
|
1111 |
|
|
begin
|
1112 |
|
|
if (ireset='0') then
|
1113 |
|
|
gp_reg_tmp <= (others=>'0');
|
1114 |
|
|
elsif (cp2='1' and cp2'event) then
|
1115 |
|
|
if (cp2en='1') then -- Clock enable
|
1116 |
|
|
-- if ((idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z) or sts_st1)='1' then -- CLOCK ENABLE
|
1117 |
|
|
if ((idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z) or idc_sts)='1' then -- CLOCK ENABLE
|
1118 |
|
|
gp_reg_tmp <= reg_rd_out;
|
1119 |
|
|
end if;
|
1120 |
|
|
end if;
|
1121 |
|
|
end if;
|
1122 |
|
|
end process;
|
1123 |
|
|
|
1124 |
|
|
-- **********************************************************************************************************
|
1125 |
|
|
|
1126 |
|
|
-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
1127 |
|
|
-- +++++++++++++++++++++++++++++++++++++++ PROGRAM COUNTER ++++++++++++++++++++++++++++++++++++++++++++++++++
|
1128 |
|
|
-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
1129 |
|
|
|
1130 |
|
|
program_counter_high_store:process(cp2,ireset)
|
1131 |
|
|
begin
|
1132 |
|
|
if ireset='0' then -- RESET
|
1133 |
|
|
program_counter_high_fr <=(others => '0');
|
1134 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1135 |
|
|
if (cp2en='1') then -- Clock enable
|
1136 |
|
|
if (idc_rcall or idc_icall or call_st1 or irq_st1) ='1' then
|
1137 |
|
|
program_counter_high_fr <= program_counter(15 downto 8); -- STORE HIGH BYTE OF THE PROGRAMM COUNTER FOR RCALL/ICALL/CALL INSTRUCTIONS AND INTERRUPTS
|
1138 |
|
|
end if;
|
1139 |
|
|
end if;
|
1140 |
|
|
end if;
|
1141 |
|
|
end process;
|
1142 |
|
|
|
1143 |
|
|
|
1144 |
|
|
program_counter_for_lpm_elpm:process(cp2,ireset)
|
1145 |
|
|
begin
|
1146 |
|
|
if ireset='0' then -- RESET
|
1147 |
|
|
program_counter_tmp<=(others => '0');
|
1148 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1149 |
|
|
if (cp2en='1') then -- Clock enable
|
1150 |
|
|
if (idc_lpm or idc_elpm) ='1' then
|
1151 |
|
|
program_counter_tmp <= program_counter;
|
1152 |
|
|
end if;
|
1153 |
|
|
end if;
|
1154 |
|
|
end if;
|
1155 |
|
|
end process;
|
1156 |
|
|
|
1157 |
|
|
pa15_pm <= rampz_out(0) and idc_elpm; -- '0' WHEN LPM INSTRUCTIONS RAMPZ(0) WHEN ELPM INSTRUCTION
|
1158 |
|
|
|
1159 |
|
|
-- OFFSET FOR BRBC/BRBS INSTRUCTIONS +63/-64
|
1160 |
|
|
offset_brbx <= "0000000000"&dex_brxx_offset(5 downto 0) when (dex_brxx_offset(6)='0') else -- +
|
1161 |
|
|
"1111111111"&dex_brxx_offset(5 downto 0); -- -
|
1162 |
|
|
|
1163 |
|
|
-- OFFSET FOR RJMP/RCALL INSTRUCTIONS +2047/-2048
|
1164 |
|
|
offset_rxx <= "00000"&dex_adr12mem_s(10 downto 0) when (dex_adr12mem_s(11)='0') else -- +
|
1165 |
|
|
"11111"&dex_adr12mem_s(10 downto 0); -- -
|
1166 |
|
|
|
1167 |
|
|
program_counter <= pc_high&pc_low;
|
1168 |
|
|
|
1169 |
|
|
program_counter_in <= program_counter + offset_brbx when ((idc_brbc or idc_brbs) and bit_test_op_out) ='1'else -- BRBC/BRBS
|
1170 |
|
|
program_counter + offset_rxx when (idc_rjmp or idc_rcall)='1'else -- RJMP/RCALL
|
1171 |
|
|
reg_z_out when (idc_ijmp or idc_icall)='1'else -- IJMP/ICALL
|
1172 |
|
|
pa15_pm®_z_out(15 downto 1) when (idc_lpm or idc_elpm) ='1'else -- LPM/ELPM
|
1173 |
|
|
instruction_reg when (jmp_st1 or call_st1)='1'else -- JMP/CALL
|
1174 |
|
|
"0000000000"&irqackad_int&'0' when irq_st1 ='1' else -- INTERRUPT
|
1175 |
|
|
dbusin&"00000000" when (ret_st1 or reti_st1)='1' else -- RET/RETI -> PC HIGH BYTE
|
1176 |
|
|
"00000000"&dbusin when (ret_st2 or reti_st2)='1' else -- RET/RETI -> PC LOW BYTE
|
1177 |
|
|
program_counter_tmp when (lpm_st1)='1' -- AFTER LPM/ELPM INSTRUCTION
|
1178 |
|
|
else program_counter+1; -- THE MOST USUAL CASE
|
1179 |
|
|
|
1180 |
|
|
|
1181 |
|
|
|
1182 |
|
|
pc_low_en <= not (idc_ld_x or idc_ld_y or idc_ld_z or idc_ldd_y or idc_ldd_z or
|
1183 |
|
|
idc_st_x or idc_st_y or idc_st_z or idc_std_y or idc_std_z or
|
1184 |
|
|
((sts_st or lds_st) and cpuwait)or
|
1185 |
|
|
idc_adiw or idc_sbiw or
|
1186 |
|
|
idc_push or idc_pop or
|
1187 |
|
|
idc_cbi or idc_sbi or
|
1188 |
|
|
rcall_st1 or icall_st1 or call_st2 or irq_st2 or cpuwait or
|
1189 |
|
|
ret_st1 or reti_st1);
|
1190 |
|
|
|
1191 |
|
|
|
1192 |
|
|
pc_high_en <= not (idc_ld_x or idc_ld_y or idc_ld_z or idc_ldd_y or idc_ldd_z or
|
1193 |
|
|
idc_st_x or idc_st_y or idc_st_z or idc_std_y or idc_std_z or
|
1194 |
|
|
((sts_st or lds_st) and cpuwait) or
|
1195 |
|
|
idc_adiw or idc_sbiw or
|
1196 |
|
|
idc_push or idc_pop or
|
1197 |
|
|
idc_cbi or idc_sbi or
|
1198 |
|
|
rcall_st1 or icall_st1 or call_st2 or irq_st2 or cpuwait or
|
1199 |
|
|
ret_st2 or reti_st2);
|
1200 |
|
|
|
1201 |
|
|
program_counter_low:process(cp2,ireset)
|
1202 |
|
|
begin
|
1203 |
|
|
if ireset='0' then -- RESET
|
1204 |
|
|
pc_low<=(others => '0');
|
1205 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1206 |
|
|
if (cp2en='1') then -- Clock enable
|
1207 |
|
|
if pc_low_en ='1' then
|
1208 |
|
|
pc_low <= program_counter_in(7 downto 0);
|
1209 |
|
|
end if;
|
1210 |
|
|
end if;
|
1211 |
|
|
end if;
|
1212 |
|
|
end process;
|
1213 |
|
|
|
1214 |
|
|
program_counter_high:process(cp2,ireset)
|
1215 |
|
|
begin
|
1216 |
|
|
if ireset='0' then -- RESET
|
1217 |
|
|
pc_high<=(others => '0');
|
1218 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1219 |
|
|
if (cp2en='1') then -- Clock enable
|
1220 |
|
|
if pc_high_en ='1' then
|
1221 |
|
|
pc_high <= program_counter_in(15 downto 8);
|
1222 |
|
|
end if;
|
1223 |
|
|
end if;
|
1224 |
|
|
end if;
|
1225 |
|
|
end process;
|
1226 |
|
|
|
1227 |
|
|
pc <= program_counter;
|
1228 |
|
|
|
1229 |
|
|
|
1230 |
|
|
program_counter_for_interrupt:process(cp2,ireset)
|
1231 |
|
|
begin
|
1232 |
|
|
if ireset='0' then -- RESET
|
1233 |
|
|
pc_for_interrupt <=(others => '0');
|
1234 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1235 |
|
|
if (cp2en='1') then -- Clock enable
|
1236 |
|
|
if irq_start ='1' then
|
1237 |
|
|
pc_for_interrupt <= program_counter;
|
1238 |
|
|
end if;
|
1239 |
|
|
end if;
|
1240 |
|
|
end if;
|
1241 |
|
|
end process;
|
1242 |
|
|
|
1243 |
|
|
-- END OF PROGRAM COUNTER
|
1244 |
|
|
|
1245 |
|
|
-- STATE MACHINES
|
1246 |
|
|
|
1247 |
|
|
skip_inst_start <= ((idc_sbrc or idc_sbrs or idc_sbic or idc_sbis) and bit_test_op_out)or
|
1248 |
|
|
(idc_cpse and alu_z_flag_out);
|
1249 |
|
|
|
1250 |
|
|
skip_instruction_sm:process(cp2,ireset)
|
1251 |
|
|
begin
|
1252 |
|
|
if ireset='0' then -- RESET
|
1253 |
|
|
nskip_inst_st0 <= '0';
|
1254 |
|
|
skip_inst_st1 <= '0';
|
1255 |
|
|
skip_inst_st2 <= '0';
|
1256 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1257 |
|
|
if (cp2en='1') then -- Clock enable
|
1258 |
|
|
nskip_inst_st0 <= (not nskip_inst_st0 and skip_inst_start) or
|
1259 |
|
|
(nskip_inst_st0 and not((skip_inst_st1 and not two_word_inst) or skip_inst_st2));
|
1260 |
|
|
skip_inst_st1 <= (not skip_inst_st1 and not nskip_inst_st0 and skip_inst_start);
|
1261 |
|
|
skip_inst_st2 <= not skip_inst_st2 and skip_inst_st1 and two_word_inst;
|
1262 |
|
|
end if;
|
1263 |
|
|
end if;
|
1264 |
|
|
end process;
|
1265 |
|
|
|
1266 |
|
|
|
1267 |
|
|
|
1268 |
|
|
alu_state_machines:process(cp2,ireset)
|
1269 |
|
|
begin
|
1270 |
|
|
if ireset='0' then -- RESET
|
1271 |
|
|
adiw_st <= '0';
|
1272 |
|
|
sbiw_st <= '0';
|
1273 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1274 |
|
|
if (cp2en='1') then -- Clock enable
|
1275 |
|
|
adiw_st <= not adiw_st and idc_adiw;
|
1276 |
|
|
sbiw_st <= not sbiw_st and idc_sbiw;
|
1277 |
|
|
end if;
|
1278 |
|
|
end if;
|
1279 |
|
|
end process;
|
1280 |
|
|
|
1281 |
|
|
|
1282 |
|
|
lpm_state_machine:process(cp2,ireset)
|
1283 |
|
|
begin
|
1284 |
|
|
if ireset='0' then -- RESET
|
1285 |
|
|
nlpm_st0 <= '0';
|
1286 |
|
|
lpm_st1 <= '0';
|
1287 |
|
|
lpm_st2 <= '0';
|
1288 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1289 |
|
|
if (cp2en='1') then -- Clock enable
|
1290 |
|
|
nlpm_st0 <= (not nlpm_st0 and (idc_lpm or idc_elpm)) or (nlpm_st0 and not lpm_st2);
|
1291 |
|
|
lpm_st1 <= (not lpm_st1 and not nlpm_st0 and (idc_lpm or idc_elpm)); -- ??
|
1292 |
|
|
lpm_st2 <= not lpm_st2 and lpm_st1;
|
1293 |
|
|
end if;
|
1294 |
|
|
end if;
|
1295 |
|
|
end process;
|
1296 |
|
|
|
1297 |
|
|
|
1298 |
|
|
lds_state_machine:process(cp2,ireset)
|
1299 |
|
|
begin
|
1300 |
|
|
if ireset='0' then -- RESET
|
1301 |
|
|
lds_st <= '0';
|
1302 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1303 |
|
|
if (cp2en='1') then -- Clock enable
|
1304 |
|
|
lds_st <= (not lds_st and idc_lds) or (lds_st and cpuwait);
|
1305 |
|
|
end if;
|
1306 |
|
|
end if;
|
1307 |
|
|
end process;
|
1308 |
|
|
|
1309 |
|
|
|
1310 |
|
|
sts_state_machine:process(cp2,ireset)
|
1311 |
|
|
begin
|
1312 |
|
|
if ireset='0' then -- RESET
|
1313 |
|
|
sts_st <= '0';
|
1314 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1315 |
|
|
if (cp2en='1') then -- Clock enable
|
1316 |
|
|
sts_st <= (not sts_st and idc_sts) or (sts_st and cpuwait);
|
1317 |
|
|
end if;
|
1318 |
|
|
end if;
|
1319 |
|
|
end process;
|
1320 |
|
|
|
1321 |
|
|
jmp_state_machine:process(cp2,ireset)
|
1322 |
|
|
begin
|
1323 |
|
|
if ireset='0' then -- RESET
|
1324 |
|
|
njmp_st0 <= '0';
|
1325 |
|
|
jmp_st1 <= '0';
|
1326 |
|
|
jmp_st2 <= '0';
|
1327 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1328 |
|
|
if (cp2en='1') then -- Clock enable
|
1329 |
|
|
njmp_st0 <= (not njmp_st0 and idc_jmp) or (njmp_st0 and not jmp_st2);
|
1330 |
|
|
jmp_st1 <= not jmp_st1 and not njmp_st0 and idc_jmp; -- ??
|
1331 |
|
|
jmp_st2 <= not jmp_st2 and jmp_st1;
|
1332 |
|
|
end if;
|
1333 |
|
|
end if;
|
1334 |
|
|
end process;
|
1335 |
|
|
|
1336 |
|
|
rcall_state_machine:process(cp2,ireset)
|
1337 |
|
|
begin
|
1338 |
|
|
if ireset='0' then -- RESET
|
1339 |
|
|
nrcall_st0 <= '0';
|
1340 |
|
|
rcall_st1 <= '0';
|
1341 |
|
|
rcall_st2 <= '0';
|
1342 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1343 |
|
|
if (cp2en='1') then -- Clock enable
|
1344 |
|
|
nrcall_st0 <= (not nrcall_st0 and idc_rcall) or (nrcall_st0 and not (rcall_st2 and not cpuwait));
|
1345 |
|
|
rcall_st1 <= (not rcall_st1 and not nrcall_st0 and idc_rcall) or (rcall_st1 and cpuwait);
|
1346 |
|
|
rcall_st2 <= (not rcall_st2 and rcall_st1 and not cpuwait) or (rcall_st2 and cpuwait);
|
1347 |
|
|
end if;
|
1348 |
|
|
end if;
|
1349 |
|
|
end process;
|
1350 |
|
|
|
1351 |
|
|
icall_state_machine:process(cp2,ireset)
|
1352 |
|
|
begin
|
1353 |
|
|
if ireset='0' then -- RESET
|
1354 |
|
|
nicall_st0 <= '0';
|
1355 |
|
|
icall_st1 <= '0';
|
1356 |
|
|
icall_st2 <= '0';
|
1357 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1358 |
|
|
if (cp2en='1') then -- Clock enable
|
1359 |
|
|
nicall_st0 <= (not nicall_st0 and idc_icall) or (nicall_st0 and not (icall_st2 and not cpuwait));
|
1360 |
|
|
icall_st1 <= (not icall_st1 and not nicall_st0 and idc_icall) or (icall_st1 and cpuwait);
|
1361 |
|
|
icall_st2 <= (not icall_st2 and icall_st1 and not cpuwait) or (icall_st2 and cpuwait);
|
1362 |
|
|
end if;
|
1363 |
|
|
end if;
|
1364 |
|
|
end process;
|
1365 |
|
|
|
1366 |
|
|
call_state_machine:process(cp2,ireset)
|
1367 |
|
|
begin
|
1368 |
|
|
if ireset='0' then -- RESET
|
1369 |
|
|
ncall_st0 <= '0';
|
1370 |
|
|
call_st1 <= '0';
|
1371 |
|
|
call_st2 <= '0';
|
1372 |
|
|
call_st3 <= '0';
|
1373 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1374 |
|
|
if (cp2en='1') then -- Clock enable
|
1375 |
|
|
ncall_st0 <= (not ncall_st0 and idc_call) or (ncall_st0 and not( call_st3 and not cpuwait));
|
1376 |
|
|
call_st1 <= not call_st1 and not ncall_st0 and idc_call;
|
1377 |
|
|
call_st2 <= (not call_st2 and call_st1) or (call_st2 and cpuwait);
|
1378 |
|
|
call_st3 <= (not call_st3 and call_st2 and not cpuwait) or (call_st3 and cpuwait);
|
1379 |
|
|
end if;
|
1380 |
|
|
end if;
|
1381 |
|
|
end process;
|
1382 |
|
|
|
1383 |
|
|
ret_state_machine:process(cp2,ireset)
|
1384 |
|
|
begin
|
1385 |
|
|
if ireset='0' then -- RESET
|
1386 |
|
|
nret_st0 <= '0';
|
1387 |
|
|
ret_st1 <= '0';
|
1388 |
|
|
ret_st2 <= '0';
|
1389 |
|
|
ret_st3 <= '0';
|
1390 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1391 |
|
|
if (cp2en='1') then -- Clock enable
|
1392 |
|
|
nret_st0 <= (not nret_st0 and idc_ret) or (nret_st0 and not ret_st3);
|
1393 |
|
|
ret_st1 <= (not ret_st1 and not nret_st0 and idc_ret) or (ret_st1 and cpuwait);
|
1394 |
|
|
ret_st2 <= (not ret_st2 and ret_st1 and not cpuwait) or (ret_st2 and cpuwait) ;
|
1395 |
|
|
ret_st3 <= not ret_st3 and ret_st2 and not cpuwait;
|
1396 |
|
|
end if;
|
1397 |
|
|
end if;
|
1398 |
|
|
end process;
|
1399 |
|
|
|
1400 |
|
|
reti_state_machine:process(cp2,ireset)
|
1401 |
|
|
begin
|
1402 |
|
|
if ireset='0' then -- RESET
|
1403 |
|
|
nreti_st0 <= '0';
|
1404 |
|
|
reti_st1 <= '0';
|
1405 |
|
|
reti_st2 <= '0';
|
1406 |
|
|
reti_st3 <= '0';
|
1407 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1408 |
|
|
if (cp2en='1') then -- Clock enable
|
1409 |
|
|
nreti_st0 <= (not nreti_st0 and idc_reti) or (nreti_st0 and not reti_st3);
|
1410 |
|
|
reti_st1 <= (not reti_st1 and not nreti_st0 and idc_reti) or (reti_st1 and cpuwait);
|
1411 |
|
|
reti_st2 <= (not reti_st2 and reti_st1 and not cpuwait) or (reti_st2 and cpuwait) ;
|
1412 |
|
|
reti_st3 <= not reti_st3 and reti_st2 and not cpuwait;
|
1413 |
|
|
end if;
|
1414 |
|
|
end if;
|
1415 |
|
|
end process;
|
1416 |
|
|
|
1417 |
|
|
|
1418 |
|
|
-- INTERRUPT LOGIC AND STATE MACHINE
|
1419 |
|
|
|
1420 |
|
|
irq_int <= '0' when irqlines="00000000000000000000000" else '1';
|
1421 |
|
|
|
1422 |
|
|
irq_vector_adr(15 downto 6)<=(others => '0');
|
1423 |
|
|
irq_vector_adr(0) <= '0';
|
1424 |
|
|
-- PRIORITY ENCODER
|
1425 |
|
|
irq_vector_adr(5 downto 1) <= "00001" when irqlines(0)='1' else -- 0x0002
|
1426 |
|
|
"00010" when irqlines(1)='1' else -- 0x0004
|
1427 |
|
|
"00011" when irqlines(2)='1' else -- 0x0006
|
1428 |
|
|
"00100" when irqlines(3)='1' else -- 0x0008
|
1429 |
|
|
"00101" when irqlines(4)='1' else -- 0x000A
|
1430 |
|
|
"00110" when irqlines(5)='1' else -- 0x000C
|
1431 |
|
|
"00111" when irqlines(6)='1' else -- 0x000E
|
1432 |
|
|
"01000" when irqlines(7)='1' else -- 0x0010
|
1433 |
|
|
"01001" when irqlines(8)='1' else -- 0x0012
|
1434 |
|
|
"01010" when irqlines(9)='1' else -- 0x0014
|
1435 |
|
|
"01011" when irqlines(10)='1' else -- 0x0016
|
1436 |
|
|
"01100" when irqlines(11)='1' else -- 0x0018
|
1437 |
|
|
"01101" when irqlines(12)='1' else -- 0x001A
|
1438 |
|
|
"01110" when irqlines(13)='1' else -- 0x001C
|
1439 |
|
|
"01111" when irqlines(14)='1' else -- 0x001E
|
1440 |
|
|
"10000" when irqlines(15)='1' else -- 0x0020
|
1441 |
|
|
"10001" when irqlines(16)='1' else -- 0x0022
|
1442 |
|
|
"10010" when irqlines(17)='1' else -- 0x0024
|
1443 |
|
|
"10011" when irqlines(18)='1' else -- 0x0026
|
1444 |
|
|
"10100" when irqlines(19)='1' else -- 0x0028
|
1445 |
|
|
"10101" when irqlines(20)='1' else -- 0x002A
|
1446 |
|
|
"10110" when irqlines(21)='1' else -- 0x002C
|
1447 |
|
|
"10111" when irqlines(22)='1' else -- 0x002E
|
1448 |
|
|
"00000";
|
1449 |
|
|
|
1450 |
|
|
-- MULTI CYCLE INSTRUCTION FLAG FOR IRQ
|
1451 |
|
|
cpu_busy <= idc_adiw or idc_sbiw or idc_cbi or idc_sbi or
|
1452 |
|
|
idc_rjmp or idc_ijmp or
|
1453 |
|
|
idc_jmp or jmp_st1 or
|
1454 |
|
|
-- idc_brbs or idc_brbc or -- Old variant
|
1455 |
|
|
((idc_brbc or idc_brbs) and bit_test_op_out) or
|
1456 |
|
|
idc_lpm or lpm_st1 or
|
1457 |
|
|
skip_inst_start or (skip_inst_st1 and two_word_inst) or
|
1458 |
|
|
idc_ld_x or idc_ld_y or idc_ldd_y or idc_ld_z or idc_ldd_z or (ld_st and cpuwait) or
|
1459 |
|
|
idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z or (st_st and cpuwait) or
|
1460 |
|
|
idc_lds or (lds_st and cpuwait) or
|
1461 |
|
|
idc_sts or (sts_st and cpuwait) or
|
1462 |
|
|
idc_rcall or rcall_st1 or (rcall_st2 and cpuwait) or -- RCALL
|
1463 |
|
|
idc_icall or icall_st1 or (icall_st2 and cpuwait) or -- ICALL
|
1464 |
|
|
idc_call or call_st1 or call_st2 or (call_st3 and cpuwait) or -- CALL
|
1465 |
|
|
idc_push or (push_st and cpuwait) or -- PUSH (added 14.07.05)
|
1466 |
|
|
idc_pop or (pop_st and cpuwait) or -- POP (added 14.07.05)
|
1467 |
|
|
(idc_bclr and sreg_bop_wr_en(7)) or -- ??? CLI
|
1468 |
|
|
(iowe_int and sreg_adr_eq and not dbusout_int(7))or -- ??? Writing '0' to I flag (OUT/STD/ST/STD)
|
1469 |
|
|
nirq_st0 or
|
1470 |
|
|
-- idc_ret or nret_st0 or -- Old variant
|
1471 |
|
|
idc_ret or ret_st1 or ret_st2 or
|
1472 |
|
|
-- idc_reti or nreti_st0; -- At least one instruction must be executed after RETI and before the new interrupt.
|
1473 |
|
|
idc_reti or reti_st1 or reti_st2;
|
1474 |
|
|
|
1475 |
|
|
sreg_adr_eq <= '1' when adr_int=SREG_Address else '0';
|
1476 |
|
|
|
1477 |
|
|
--irq_start <= irq_int and not cpu_busy and globint;
|
1478 |
|
|
irq_start <= irq_int and not cpu_busy and globint;
|
1479 |
|
|
|
1480 |
|
|
irq_state_machine:process(cp2,ireset)
|
1481 |
|
|
begin
|
1482 |
|
|
if ireset='0' then -- RESET
|
1483 |
|
|
nirq_st0 <= '0';
|
1484 |
|
|
irq_st1 <= '0';
|
1485 |
|
|
irq_st2 <= '0';
|
1486 |
|
|
irq_st3 <= '0';
|
1487 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1488 |
|
|
if (cp2en='1') then -- Clock enable
|
1489 |
|
|
nirq_st0 <= (not nirq_st0 and irq_start) or (nirq_st0 and not (irq_st3 and not cpuwait));
|
1490 |
|
|
irq_st1 <= (not irq_st1 and not nirq_st0 and irq_start);
|
1491 |
|
|
irq_st2 <= (not irq_st2 and irq_st1) or (irq_st2 and cpuwait);
|
1492 |
|
|
irq_st3 <= (not irq_st3 and irq_st2 and not cpuwait) or (irq_st3 and cpuwait);
|
1493 |
|
|
end if;
|
1494 |
|
|
end if;
|
1495 |
|
|
end process;
|
1496 |
|
|
|
1497 |
|
|
irqack_reg:process(cp2,ireset)
|
1498 |
|
|
begin
|
1499 |
|
|
if ireset='0' then -- RESET
|
1500 |
|
|
irqack_int<='0';
|
1501 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1502 |
|
|
if (cp2en='1') then -- Clock enable
|
1503 |
|
|
irqack_int<= not irqack_int and irq_start;
|
1504 |
|
|
end if;
|
1505 |
|
|
end if;
|
1506 |
|
|
end process;
|
1507 |
|
|
irqack <= irqack_int;
|
1508 |
|
|
|
1509 |
|
|
irqackad_reg:process(cp2,ireset)
|
1510 |
|
|
begin
|
1511 |
|
|
if ireset='0' then -- RESET
|
1512 |
|
|
irqackad_int<=(others=>'0');
|
1513 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1514 |
|
|
if (cp2en='1') then -- Clock enable
|
1515 |
|
|
irqackad_int <= irq_vector_adr(5 downto 1);
|
1516 |
|
|
end if;
|
1517 |
|
|
end if;
|
1518 |
|
|
end process;
|
1519 |
|
|
irqackad <= irqackad_int;
|
1520 |
|
|
|
1521 |
|
|
-- *******************************************************************************************
|
1522 |
|
|
|
1523 |
|
|
rjmp_push_pop_ijmp_state_brxx_machine:process(cp2,ireset)
|
1524 |
|
|
begin
|
1525 |
|
|
if ireset='0' then -- RESET
|
1526 |
|
|
rjmp_st <= '0';
|
1527 |
|
|
ijmp_st <= '0';
|
1528 |
|
|
push_st <= '0';
|
1529 |
|
|
pop_st <= '0';
|
1530 |
|
|
brxx_st <= '0';
|
1531 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1532 |
|
|
if (cp2en='1') then -- Clock enable
|
1533 |
|
|
rjmp_st <= idc_rjmp; -- ??
|
1534 |
|
|
ijmp_st <= idc_ijmp;
|
1535 |
|
|
push_st <= (not push_st and idc_push) or (push_st and cpuwait);
|
1536 |
|
|
pop_st <= (not pop_st and idc_pop) or (pop_st and cpuwait);
|
1537 |
|
|
brxx_st <= not brxx_st and (idc_brbc or idc_brbs) and bit_test_op_out;
|
1538 |
|
|
end if;
|
1539 |
|
|
end if;
|
1540 |
|
|
end process;
|
1541 |
|
|
|
1542 |
|
|
-- LD/LDD/ST/STD
|
1543 |
|
|
ld_st_state_machine:process(cp2,ireset)
|
1544 |
|
|
begin
|
1545 |
|
|
if ireset='0' then -- RESET
|
1546 |
|
|
ld_st <= '0';
|
1547 |
|
|
st_st <= '0';
|
1548 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1549 |
|
|
if (cp2en='1') then -- Clock enable
|
1550 |
|
|
ld_st <= (not ld_st and (idc_ld_x or idc_ld_y or idc_ldd_y or idc_ld_z or idc_ldd_z)) or (ld_st and cpuwait);
|
1551 |
|
|
st_st <= (not st_st and (idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)) or (st_st and cpuwait);
|
1552 |
|
|
end if;
|
1553 |
|
|
end if;
|
1554 |
|
|
end process;
|
1555 |
|
|
|
1556 |
|
|
-- SBI/CBI
|
1557 |
|
|
sbi_cbi_machine:process(cp2,ireset)
|
1558 |
|
|
begin
|
1559 |
|
|
if ireset='0' then -- RESET
|
1560 |
|
|
sbi_st <= '0';
|
1561 |
|
|
cbi_st <= '0';
|
1562 |
|
|
cbi_sbi_io_adr_tmp <= (others => '0');
|
1563 |
|
|
cbi_sbi_bit_num_tmp <= (others => '0');
|
1564 |
|
|
elsif (cp2='1' and cp2'event) then -- CLOCK
|
1565 |
|
|
if (cp2en='1') then -- Clock enable
|
1566 |
|
|
sbi_st <= not sbi_st and idc_sbi;
|
1567 |
|
|
cbi_st <= not cbi_st and idc_cbi;
|
1568 |
|
|
cbi_sbi_io_adr_tmp <= dex_adr5port;
|
1569 |
|
|
cbi_sbi_bit_num_tmp <= dex_bitop_bitnum;
|
1570 |
|
|
end if;
|
1571 |
|
|
end if;
|
1572 |
|
|
end process;
|
1573 |
|
|
|
1574 |
|
|
-- ########################################################################################
|
1575 |
|
|
|
1576 |
|
|
-- SREG FLAGS WRITE ENABLE LOGIC
|
1577 |
|
|
|
1578 |
|
|
--bclr_bset_op_en_logic:for i in sreg_bop_wr_en'range generate
|
1579 |
|
|
--sreg_bop_wr_en(i) <= '1' when (dex_bitnum_sreg=i and (idc_bclr or idc_bset)='1') else '0';
|
1580 |
|
|
--end generate;
|
1581 |
|
|
|
1582 |
|
|
sreg_bop_wr_en(0) <= '1' when (dex_bitnum_sreg=0 and (idc_bclr or idc_bset)='1') else '0';
|
1583 |
|
|
sreg_bop_wr_en(1) <= '1' when (dex_bitnum_sreg=1 and (idc_bclr or idc_bset)='1') else '0';
|
1584 |
|
|
sreg_bop_wr_en(2) <= '1' when (dex_bitnum_sreg=2 and (idc_bclr or idc_bset)='1') else '0';
|
1585 |
|
|
sreg_bop_wr_en(3) <= '1' when (dex_bitnum_sreg=3 and (idc_bclr or idc_bset)='1') else '0';
|
1586 |
|
|
sreg_bop_wr_en(4) <= '1' when (dex_bitnum_sreg=4 and (idc_bclr or idc_bset)='1') else '0';
|
1587 |
|
|
sreg_bop_wr_en(5) <= '1' when (dex_bitnum_sreg=5 and (idc_bclr or idc_bset)='1') else '0';
|
1588 |
|
|
sreg_bop_wr_en(6) <= '1' when (dex_bitnum_sreg=6 and (idc_bclr or idc_bset)='1') else '0';
|
1589 |
|
|
sreg_bop_wr_en(7) <= '1' when (dex_bitnum_sreg=7 and (idc_bclr or idc_bset)='1') else '0';
|
1590 |
|
|
|
1591 |
|
|
sreg_c_wr_en <= idc_add or idc_adc or (idc_adiw or adiw_st) or idc_sub or idc_subi or
|
1592 |
|
|
idc_sbc or idc_sbci or (idc_sbiw or sbiw_st) or idc_com or idc_neg or
|
1593 |
|
|
idc_cp or idc_cpc or idc_cpi or
|
1594 |
|
|
idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(0);
|
1595 |
|
|
|
1596 |
|
|
sreg_z_wr_en <= idc_add or idc_adc or (idc_adiw or adiw_st) or idc_sub or idc_subi or
|
1597 |
|
|
idc_sbc or idc_sbci or (idc_sbiw or sbiw_st) or
|
1598 |
|
|
idc_cp or idc_cpc or idc_cpi or
|
1599 |
|
|
idc_and or idc_andi or idc_or or idc_ori or idc_eor or idc_com or idc_neg or
|
1600 |
|
|
idc_inc or idc_dec or idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(1);
|
1601 |
|
|
|
1602 |
|
|
|
1603 |
|
|
sreg_n_wr_en <= idc_add or idc_adc or adiw_st or idc_sub or idc_subi or
|
1604 |
|
|
idc_sbc or idc_sbci or sbiw_st or
|
1605 |
|
|
idc_cp or idc_cpc or idc_cpi or
|
1606 |
|
|
idc_and or idc_andi or idc_or or idc_ori or idc_eor or idc_com or idc_neg or
|
1607 |
|
|
idc_inc or idc_dec or idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(2);
|
1608 |
|
|
|
1609 |
|
|
sreg_v_wr_en <= idc_add or idc_adc or adiw_st or idc_sub or idc_subi or -- idc_adiw
|
1610 |
|
|
idc_sbc or idc_sbci or sbiw_st or idc_neg or idc_com or -- idc_sbiw
|
1611 |
|
|
idc_inc or idc_dec or
|
1612 |
|
|
idc_cp or idc_cpc or idc_cpi or
|
1613 |
|
|
idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(3) or
|
1614 |
|
|
idc_and or idc_andi or idc_or or idc_ori or idc_eor; -- V-flag bug fixing
|
1615 |
|
|
|
1616 |
|
|
sreg_s_wr_en <= idc_add or idc_adc or adiw_st or idc_sub or idc_subi or
|
1617 |
|
|
idc_sbc or idc_sbci or sbiw_st or
|
1618 |
|
|
idc_cp or idc_cpc or idc_cpi or
|
1619 |
|
|
idc_and or idc_andi or idc_or or idc_ori or idc_eor or idc_com or idc_neg or
|
1620 |
|
|
idc_inc or idc_dec or idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(4);
|
1621 |
|
|
|
1622 |
|
|
sreg_h_wr_en <= idc_add or idc_adc or idc_sub or idc_subi or
|
1623 |
|
|
idc_cp or idc_cpc or idc_cpi or
|
1624 |
|
|
idc_sbc or idc_sbci or idc_neg or sreg_bop_wr_en(5);
|
1625 |
|
|
|
1626 |
|
|
sreg_t_wr_en <= idc_bst or sreg_bop_wr_en(6);
|
1627 |
|
|
|
1628 |
|
|
sreg_i_wr_en <= irq_st1 or reti_st3 or sreg_bop_wr_en(7); -- WAS "irq_start"
|
1629 |
|
|
|
1630 |
|
|
sreg_fl_in <= bit_pr_sreg_out when (idc_bst or idc_bclr or idc_bset)='1' else -- TO THE SREG
|
1631 |
|
|
reti_st3&'0'&alu_h_flag_out&alu_s_flag_out&alu_v_flag_out&alu_n_flag_out&alu_z_flag_out&alu_c_flag_out;
|
1632 |
|
|
|
1633 |
|
|
-- #################################################################################################################
|
1634 |
|
|
|
1635 |
|
|
-- *********************************************************************************************
|
1636 |
|
|
-- ************** INSTRUCTION DECODER OUTPUTS FOR THE OTHER BLOCKS ****************************
|
1637 |
|
|
-- *********************************************************************************************
|
1638 |
|
|
|
1639 |
|
|
-- FOR ALU
|
1640 |
|
|
|
1641 |
|
|
idc_add_out <= idc_add;
|
1642 |
|
|
idc_adc_out <= idc_adc;
|
1643 |
|
|
idc_adiw_out <= idc_adiw;
|
1644 |
|
|
idc_sub_out <= idc_sub;
|
1645 |
|
|
idc_subi_out <= idc_subi;
|
1646 |
|
|
idc_sbc_out <= idc_sbc;
|
1647 |
|
|
idc_sbci_out <= idc_sbci;
|
1648 |
|
|
idc_sbiw_out <= idc_sbiw;
|
1649 |
|
|
adiw_st_out <= adiw_st;
|
1650 |
|
|
sbiw_st_out <= sbiw_st;
|
1651 |
|
|
idc_and_out <= idc_and;
|
1652 |
|
|
idc_andi_out <= idc_andi;
|
1653 |
|
|
idc_or_out <= idc_or;
|
1654 |
|
|
idc_ori_out <= idc_ori;
|
1655 |
|
|
idc_eor_out <= idc_eor;
|
1656 |
|
|
idc_com_out <= idc_com;
|
1657 |
|
|
idc_neg_out <= idc_neg;
|
1658 |
|
|
idc_inc_out <= idc_inc;
|
1659 |
|
|
idc_dec_out <= idc_dec;
|
1660 |
|
|
idc_cp_out <= idc_cp;
|
1661 |
|
|
idc_cpc_out <= idc_cpc;
|
1662 |
|
|
idc_cpi_out <= idc_cpi;
|
1663 |
|
|
idc_cpse_out <= idc_cpse;
|
1664 |
|
|
idc_lsr_out <= idc_lsr;
|
1665 |
|
|
idc_ror_out <= idc_ror;
|
1666 |
|
|
idc_asr_out <= idc_asr;
|
1667 |
|
|
idc_swap_out <= idc_swap;
|
1668 |
|
|
|
1669 |
|
|
-- FOR THE BIT PROCESSOR
|
1670 |
|
|
sbi_st_out <= sbi_st;
|
1671 |
|
|
cbi_st_out <= cbi_st;
|
1672 |
|
|
idc_bst_out <= idc_bst;
|
1673 |
|
|
idc_bset_out <= idc_bset;
|
1674 |
|
|
idc_bclr_out <= idc_bclr;
|
1675 |
|
|
idc_sbic_out <= idc_sbic;
|
1676 |
|
|
idc_sbis_out <= idc_sbis;
|
1677 |
|
|
idc_sbrs_out <= idc_sbrs;
|
1678 |
|
|
idc_sbrc_out <= idc_sbrc;
|
1679 |
|
|
idc_brbs_out <= idc_brbs;
|
1680 |
|
|
idc_brbc_out <= idc_brbc;
|
1681 |
|
|
idc_reti_out <= idc_reti;
|
1682 |
|
|
|
1683 |
|
|
-- POST INCREMENT/PRE DECREMENT FOR THE X,Y,Z REGISTERS
|
1684 |
|
|
post_inc <= idc_psinc;
|
1685 |
|
|
pre_dec <= idc_prdec;
|
1686 |
|
|
reg_h_wr <= (idc_st_x or idc_st_y or idc_st_z or idc_ld_x or idc_ld_y or idc_ld_z) and (idc_psinc or idc_prdec);
|
1687 |
|
|
|
1688 |
|
|
reg_h_adr(0)<= idc_st_x or idc_ld_x;
|
1689 |
|
|
reg_h_adr(1)<= idc_st_y or idc_std_y or idc_ld_y or idc_ldd_y;
|
1690 |
|
|
reg_h_adr(2)<= idc_st_z or idc_std_z or idc_ld_z or idc_ldd_z;
|
1691 |
|
|
|
1692 |
|
|
-- STACK POINTER CONTROL
|
1693 |
|
|
sp_ndown_up <= idc_pop or idc_ret or (ret_st1 and not cpuwait) or idc_reti or (reti_st1 and not cpuwait); -- ?????????
|
1694 |
|
|
sp_en <= idc_push or idc_pop or idc_rcall or (rcall_st1 and not cpuwait) or idc_icall or (icall_st1 and not cpuwait) or
|
1695 |
|
|
idc_ret or (ret_st1 and not cpuwait) or idc_reti or (reti_st1 and not cpuwait) or
|
1696 |
|
|
call_st1 or (call_st2 and not cpuwait) or irq_st1 or (irq_st2 and not cpuwait); --????????
|
1697 |
|
|
|
1698 |
|
|
|
1699 |
|
|
branch <= dex_condition;
|
1700 |
|
|
bit_num_r_io <= cbi_sbi_bit_num_tmp when (cbi_st or sbi_st)='1' else dex_bitop_bitnum;
|
1701 |
|
|
|
1702 |
|
|
adr <= adr_int;
|
1703 |
|
|
|
1704 |
|
|
ramre <= ramre_int;
|
1705 |
|
|
ramwe <= ramwe_int;
|
1706 |
|
|
|
1707 |
|
|
iore <= iore_int;
|
1708 |
|
|
iowe <= iowe_int;
|
1709 |
|
|
|
1710 |
|
|
--dbusout <= dbusout_int;
|
1711 |
|
|
|
1712 |
|
|
-- Sleep Control
|
1713 |
|
|
sleepi <= idc_sleep;
|
1714 |
|
|
irqok <= irq_int;
|
1715 |
|
|
|
1716 |
|
|
-- Watchdog
|
1717 |
|
|
wdri <= idc_wdr;
|
1718 |
|
|
|
1719 |
|
|
-- ************************** JTAG OCD support ************************************
|
1720 |
|
|
|
1721 |
|
|
-- Change of flow
|
1722 |
|
|
change_flow <= '0';
|
1723 |
|
|
valid_instr <= '0';
|
1724 |
|
|
|
1725 |
|
|
|
1726 |
|
|
end RTL;
|