1 |
12 |
alfik |
/*
|
2 |
|
|
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
|
3 |
|
|
*
|
4 |
|
|
* Redistribution and use in source and binary forms, with or without modification, are
|
5 |
|
|
* permitted provided that the following conditions are met:
|
6 |
|
|
*
|
7 |
|
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
8 |
|
|
* conditions and the following disclaimer.
|
9 |
|
|
*
|
10 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
11 |
|
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
12 |
|
|
* provided with the distribution.
|
13 |
|
|
*
|
14 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
15 |
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
16 |
|
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
|
17 |
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
18 |
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
19 |
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
20 |
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
21 |
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
22 |
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23 |
|
|
*/
|
24 |
|
|
|
25 |
|
|
/*! \file ao68000.v
|
26 |
|
|
* \brief Main ao68000 IP Core source file.
|
27 |
|
|
*/
|
28 |
|
|
|
29 |
|
|
/***********************************************************************************************************************
|
30 |
|
|
* Definitions of microcode operations - parsed by ao68000_tool to generate the defines in the section below
|
31 |
|
|
**********************************************************************************************************************/
|
32 |
|
|
// OPERATIONS START
|
33 |
|
|
`define EA_REG_IDLE 3'd0
|
34 |
|
|
`define EA_REG_IR_2_0 3'd1
|
35 |
|
|
`define EA_REG_IR_11_9 3'd2
|
36 |
|
|
`define EA_REG_MOVEM_REG_2_0 3'd3
|
37 |
|
|
`define EA_REG_3b111 3'd4
|
38 |
|
|
`define EA_REG_3b100 3'd5
|
39 |
|
|
|
40 |
|
|
`define EA_MOD_IDLE 4'd0
|
41 |
|
|
`define EA_MOD_IR_5_3 4'd1
|
42 |
|
|
`define EA_MOD_MOVEM_MOD_5_3 4'd2
|
43 |
|
|
`define EA_MOD_IR_8_6 4'd3
|
44 |
|
|
`define EA_MOD_PREDEC 4'd4 // predecrement: -(An)
|
45 |
|
|
`define EA_MOD_3b111 4'd5 // extended mod
|
46 |
|
|
`define EA_MOD_DN_PREDEC 4'd6 // MOD.DN_PREDEC: Dn 3'b000 (ir[3] == 1'b0), -(An) 3'b100 (ir[3] == 1'b1)
|
47 |
|
|
`define EA_MOD_DN_AN_EXG 4'd7 // MOD.DN_AN_EXG: Dn 3'b000 (ir[7:3] == 5'b01000 or 5'b10001), An 3'b001 (ir[7:3] == 5'b01001)
|
48 |
|
|
`define EA_MOD_POSTINC 4'd8 // MOD.POSTINC: postincrement (An)+ 3'b011
|
49 |
|
|
`define EA_MOD_AN 4'd9 // MOD.AN: An 3'b001, saved result is sign-extended
|
50 |
|
|
`define EA_MOD_DN 4'd10 // MOD.DN: Dn 3'b000
|
51 |
|
|
`define EA_MOD_INDIRECTOFFSET 4'd11 // MOD.INDIRECTOFFSET: (d16, An) 3'b101
|
52 |
|
|
|
53 |
|
|
`define EA_TYPE_IDLE 4'd0
|
54 |
|
|
`define EA_TYPE_ALL 4'd1 // TYPE.ALL: all
|
55 |
|
|
`define EA_TYPE_CONTROL_POSTINC 4'd2 // TYPE.CONTROL_POSTINC: control or postincrement
|
56 |
|
|
`define EA_TYPE_CONTROLALTER_PREDEC 4'd3 // TYPE.CONTROLALTER_PREDEC: control alter or predecrement
|
57 |
|
|
`define EA_TYPE_CONTROL 4'd4 // TYPE.CONTROL: control
|
58 |
|
|
`define EA_TYPE_DATAALTER 4'd5 // TYPE.DATAALTER: data alter
|
59 |
|
|
`define EA_TYPE_DN_AN 4'd6 // TYPE.DN_AN: Dn, An
|
60 |
|
|
`define EA_TYPE_MEMORYALTER 4'd7 // TYPE.MEMORYALTER: memory alter
|
61 |
|
|
`define EA_TYPE_DATA 4'd8 // TYPE.DATA: data
|
62 |
|
|
|
63 |
|
|
`define OP1_IDLE 4'd0
|
64 |
|
|
`define OP1_FROM_OP2 4'd1 // move from operand2
|
65 |
|
|
`define OP1_FROM_ADDRESS 4'd2 // move from address
|
66 |
|
|
`define OP1_FROM_DATA 4'd3 // move from data, sign extend
|
67 |
|
|
`define OP1_FROM_IMMEDIATE 4'd4 // move immediate, sign extend
|
68 |
|
|
`define OP1_FROM_RESULT 4'd5 // move from result
|
69 |
|
|
`define OP1_MOVEQ 4'd6 // move moveq: { 24{ir[7]}, ir[7:0] }
|
70 |
|
|
`define OP1_FROM_PC 4'd7 // move from PC
|
71 |
|
|
`define OP1_LOAD_ZEROS 4'd8 // load zeros: 32'b0
|
72 |
|
|
`define OP1_LOAD_ONES 4'd9 // load ones: 32'hFFFFFFFF
|
73 |
|
|
`define OP1_FROM_SR 4'd10 // move from SR
|
74 |
|
|
`define OP1_FROM_USP 4'd11 // move from USP
|
75 |
|
|
`define OP1_FROM_AN 4'd12 // move from An, 32 bits
|
76 |
|
|
`define OP1_FROM_DN 4'd13 // move from Dn, sign extend
|
77 |
|
|
`define OP1_FROM_IR 4'd14 // move from ir[15:0]
|
78 |
|
|
`define OP1_FROM_FAULT_ADDRESS 4'd15 // move from fault_address
|
79 |
|
|
|
80 |
|
|
`define OP2_IDLE 3'd0
|
81 |
|
|
`define OP2_FROM_OP1 3'd1 // move from operand1
|
82 |
|
|
`define OP2_LOAD_1 3'd2 // load: 32'b1
|
83 |
|
|
`define OP2_LOAD_COUNT 3'd3 // load count
|
84 |
|
|
`define OP2_ADDQ_SUBQ 3'd4 // load addq_subq
|
85 |
|
|
`define OP2_MOVE_OFFSET 3'd5 // move offset
|
86 |
|
|
`define OP2_MOVE_ADDRESS_BUS_INFO 3'd6 // move address_bus_info
|
87 |
|
|
`define OP2_DECR_BY_1 3'd7 // decrement by 1
|
88 |
|
|
|
89 |
|
|
`define ADDRESS_IDLE 4'd0
|
90 |
|
|
`define ADDRESS_INCR_BY_SIZE 4'd1 // increment by size
|
91 |
|
|
`define ADDRESS_DECR_BY_SIZE 4'd2 // decrement by size
|
92 |
|
|
`define ADDRESS_INCR_BY_2 4'd3 // increment by 2
|
93 |
|
|
`define ADDRESS_FROM_AN_OUTPUT 4'd4 // move from An output
|
94 |
|
|
`define ADDRESS_FROM_BASE_INDEX_OFFSET 4'd5 // move from base+index+offset
|
95 |
|
|
`define ADDRESS_FROM_IMM_16 4'd6 // move from {16{ir1[15]}, ir1[15:0]}
|
96 |
|
|
`define ADDRESS_FROM_IMM_32 4'd7 // move from {ir1[15:0], ir2[15:0]}
|
97 |
|
|
`define ADDRESS_FROM_PC_INDEX_OFFSET 4'd8 // move from pc+index+offset
|
98 |
|
|
`define ADDRESS_FROM_TRAP 4'd9 // move trap {22'b0, trap[7:0], 2'b0}
|
99 |
|
|
|
100 |
|
|
`define SIZE_IDLE 4'd0
|
101 |
15 |
alfik |
`define SIZE_BYTE 4'd1 // load byte: 3'b001
|
102 |
|
|
`define SIZE_WORD 4'd2 // load word: 3'b010
|
103 |
|
|
`define SIZE_LONG 4'd3 // load long: 3'b100
|
104 |
12 |
alfik |
`define SIZE_1 4'd4 // SIZE.1: word ( ir[7:6] == 2'b00 ), long ( ir[7:6] == 2'b01 )
|
105 |
|
|
`define SIZE_1_PLUS 4'd5 // SIZE.1+: word ( ir[7:6] == 2'b10 ), long ( ir[7:6] == 2'b11 )
|
106 |
|
|
`define SIZE_2 4'd6 // SIZE.2: word ( ir[6] == 1'b0 ), long ( ir[6] == 1'b1 )
|
107 |
|
|
`define SIZE_3 4'd7 // SIZE.3: byte ( ir[7:6] == 2'b00 ), word ( ir[7:6] == 2'b01 ), long ( ir[7:6] == 2'b10 )
|
108 |
|
|
`define SIZE_4 4'd8 // SIZE.4: byte ( ir[13:12] == 2'b01 ), word( ir[13:12] == 2'b11 ), long ( ir[13:12] == 2'b10 )
|
109 |
|
|
`define SIZE_5 4'd9 // SIZE.5: word ( ir[8] == 1'b0 ), long ( ir[8] == 1'b1 )
|
110 |
|
|
`define SIZE_6 4'd10 // SIZE.6: byte ( ir[5:3] != 3'b000 ), long ( ir[5:3] == 3'b000 )
|
111 |
|
|
|
112 |
|
|
`define MOVEM_MODREG_IDLE 3'd0
|
113 |
|
|
`define MOVEM_MODREG_LOAD_0 3'd1 // load 6'b0
|
114 |
|
|
`define MOVEM_MODREG_LOAD_6b001111 3'd2 // load 6'b001111
|
115 |
|
|
`define MOVEM_MODREG_INCR_BY_1 3'd3 // increment by 1
|
116 |
|
|
`define MOVEM_MODREG_DECR_BY_1 3'd4 // decrement by 1
|
117 |
|
|
|
118 |
|
|
`define MOVEM_LOOP_IDLE 2'd0
|
119 |
|
|
`define MOVEM_LOOP_LOAD_0 2'd1 // load 4'b0
|
120 |
|
|
`define MOVEM_LOOP_INCR_BY_1 2'd2 // increment by 1
|
121 |
|
|
|
122 |
|
|
`define MOVEM_REG_IDLE 2'd0
|
123 |
|
|
`define MOVEM_REG_FROM_OP1 2'd1 // load from operand1[15:0]
|
124 |
|
|
`define MOVEM_REG_SHIFT_RIGHT 2'd2 // shift right
|
125 |
|
|
|
126 |
|
|
`define IR_IDLE 2'd0
|
127 |
|
|
`define IR_LOAD_WHEN_PREFETCH_VALID 2'd1 // load from prefetch_ir[79:64]
|
128 |
|
|
|
129 |
|
|
`define PC_IDLE 3'd0
|
130 |
|
|
`define PC_FROM_RESULT 3'd1 // move from result
|
131 |
|
|
`define PC_INCR_BY_2 3'd2 // increment by 2
|
132 |
|
|
`define PC_INCR_BY_4 3'd3 // increment by 4
|
133 |
13 |
alfik |
`define PC_INCR_BY_SIZE 3'd4 // increment by size: 2 (size == 3'b001 || size == 3'b010), 4 (size == 3'b100)
|
134 |
12 |
alfik |
`define PC_FROM_PREFETCH_IR 3'd5 // move from prefetch_ir
|
135 |
|
|
`define PC_INCR_BY_2_IN_MAIN_LOOP 3'd6 // increment by 2, in main loop, when valid prefetch and valid instruction
|
136 |
|
|
|
137 |
|
|
`define TRAP_IDLE 4'd0
|
138 |
|
|
`define TRAP_ILLEGAL_INSTR 4'd1 // move illegal_instr: 8'd4
|
139 |
|
|
`define TRAP_DIV_BY_ZERO 4'd2 // move divide_by_zero: 8'd5
|
140 |
|
|
`define TRAP_CHK 4'd3 // move chk: 8'd6
|
141 |
|
|
`define TRAP_TRAPV 4'd4 // move trapv: 8'd7
|
142 |
|
|
`define TRAP_PRIVIL_VIOLAT 4'd5 // move priv_viol: 8'd8
|
143 |
|
|
`define TRAP_TRACE 4'd6 // move trace: 8'd9
|
144 |
|
|
`define TRAP_TRAP 4'd7 // move trap: { 3'b0, 1'b1, ir[3:0] }
|
145 |
|
|
`define TRAP_FROM_DECODER 4'd8 // move from decoder_trap
|
146 |
|
|
`define TRAP_FROM_INTERRUPT 4'd9 // move from interrupt_trap
|
147 |
|
|
|
148 |
|
|
`define OFFSET_IDLE 2'd0
|
149 |
|
|
`define OFFSET_IMM_8 2'd1 // { 24{ir1[7]}, ir1[7:0] }
|
150 |
|
|
`define OFFSET_IMM_16 2'd2 // { 16{ir1[15]}, ir1[15:0] }
|
151 |
|
|
|
152 |
|
|
`define INDEX_IDLE 2'd0
|
153 |
|
|
`define INDEX_0 2'd1 // 32'b0
|
154 |
|
|
`define INDEX_LOAD_EXTENDED 2'd2 // load from extended instruction word
|
155 |
|
|
|
156 |
|
|
`define STOP_FLAG_IDLE 2'd0
|
157 |
|
|
`define STOP_FLAG_SET 2'd1 // set, continue when: trace,interrupt or reset
|
158 |
|
|
`define STOP_FLAG_CLEAR 2'd2 // clear
|
159 |
|
|
|
160 |
|
|
`define TRACE_FLAG_IDLE 2'd0
|
161 |
|
|
`define TRACE_FLAG_COPY_WHEN_NO_STOP 2'd1 // remember trace bit, move from sr[15]
|
162 |
|
|
|
163 |
|
|
`define GROUP_0_FLAG_IDLE 2'd0
|
164 |
|
|
`define GROUP_0_FLAG_SET 2'd1 // set, processing group zero exception
|
165 |
|
|
`define GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH 2'd2 // clear
|
166 |
|
|
|
167 |
|
|
`define INSTRUCTION_FLAG_IDLE 2'd0
|
168 |
|
|
`define INSTRUCTION_FLAG_SET 2'd1 // set, processing instruction
|
169 |
|
|
`define INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP 2'd2 // clear, in main loop, when valid prefetch and valid instruction
|
170 |
|
|
|
171 |
|
|
`define READ_MODIFY_WRITE_FLAG_IDLE 2'd0
|
172 |
|
|
`define READ_MODIFY_WRITE_FLAG_SET 2'd1 // set, execute a RMW cycle
|
173 |
|
|
`define READ_MODIFY_WRITE_FLAG_CLEAR 2'd2 // clear
|
174 |
|
|
|
175 |
|
|
`define DO_RESET_FLAG_IDLE 2'd0
|
176 |
|
|
`define DO_RESET_FLAG_SET 2'd1 // set, signal reset
|
177 |
|
|
`define DO_RESET_FLAG_CLEAR 2'd2 // clear
|
178 |
|
|
|
179 |
|
|
`define DO_INTERRUPT_FLAG_IDLE 2'd0
|
180 |
|
|
`define DO_INTERRUPT_FLAG_SET_IF_ACTIVE 2'd1 // set if interrupt active
|
181 |
|
|
`define DO_INTERRUPT_FLAG_CLEAR 2'd2 // clear
|
182 |
|
|
|
183 |
|
|
`define DO_READ_FLAG_IDLE 2'd0
|
184 |
|
|
`define DO_READ_FLAG_SET 2'd1 // set, perform read operation
|
185 |
|
|
`define DO_READ_FLAG_CLEAR 2'd2 // clear
|
186 |
|
|
|
187 |
|
|
`define DO_WRITE_FLAG_IDLE 2'd0
|
188 |
|
|
`define DO_WRITE_FLAG_SET 2'd1 // set, perform write operation
|
189 |
|
|
`define DO_WRITE_FLAG_CLEAR 2'd2 // clear
|
190 |
|
|
|
191 |
|
|
`define DO_BLOCKED_FLAG_IDLE 2'd0
|
192 |
|
|
`define DO_BLOCKED_FLAG_SET 2'd1 // set, block processor
|
193 |
|
|
|
194 |
|
|
`define DATA_WRITE_IDLE 2'd0
|
195 |
|
|
`define DATA_WRITE_FROM_RESULT 2'd1 // load data write register from result register
|
196 |
|
|
|
197 |
|
|
`define AN_ADDRESS_IDLE 2'd0 // load from ea_reg, user or supervisor
|
198 |
|
|
`define AN_ADDRESS_FROM_EXTENDED 2'd1 // load from extended instruction word: ir1[14:12], user or supervisor
|
199 |
|
|
`define AN_ADDRESS_USP 2'd2 // load USP address
|
200 |
|
|
`define AN_ADDRESS_SSP 2'd3 // load SSP address
|
201 |
|
|
|
202 |
|
|
`define AN_WRITE_ENABLE_IDLE 1'd0
|
203 |
|
|
`define AN_WRITE_ENABLE_SET 1'd1 // set write enable on An register
|
204 |
|
|
|
205 |
|
|
`define AN_INPUT_IDLE 2'd0 // load from result
|
206 |
|
|
`define AN_INPUT_FROM_ADDRESS 2'd1 // load from address
|
207 |
|
|
`define AN_INPUT_FROM_PREFETCH_IR 2'd2 // load from prefetch_ir, for reset, for SSP
|
208 |
|
|
|
209 |
|
|
`define DN_ADDRESS_IDLE 1'd0 // load from ea_reg
|
210 |
|
|
`define DN_ADDRESS_FROM_EXTENDED 1'd1 // load from extended instruction word: ir1[14:12]
|
211 |
|
|
|
212 |
|
|
`define DN_WRITE_ENABLE_IDLE 1'd0
|
213 |
|
|
`define DN_WRITE_ENABLE_SET 1'd1 // set write enable on Dn register
|
214 |
|
|
|
215 |
|
|
`define ALU_IDLE 5'd0
|
216 |
|
|
`define ALU_SR_SET_INTERRUPT 5'd1
|
217 |
|
|
`define ALU_SR_SET_TRAP 5'd2
|
218 |
|
|
`define ALU_MOVEP_M2R_1 5'd3
|
219 |
|
|
`define ALU_MOVEP_M2R_2 5'd4
|
220 |
|
|
`define ALU_MOVEP_M2R_3 5'd5
|
221 |
|
|
`define ALU_MOVEP_M2R_4 5'd6
|
222 |
|
|
`define ALU_MOVEP_R2M_1 5'd7
|
223 |
|
|
`define ALU_MOVEP_R2M_2 5'd8
|
224 |
|
|
`define ALU_MOVEP_R2M_3 5'd9
|
225 |
|
|
`define ALU_MOVEP_R2M_4 5'd10
|
226 |
|
|
`define ALU_SIGN_EXTEND 5'd11
|
227 |
|
|
`define ALU_ARITHMETIC_LOGIC 5'd12
|
228 |
17 |
alfik |
`define ALU_ABCD_SBCD_ADDX_SUBX_prepare 5'd13
|
229 |
|
|
`define ALU_ABCD_SBCD_ADDX_SUBX 5'd14
|
230 |
|
|
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare 5'd15
|
231 |
|
|
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR 5'd16
|
232 |
|
|
`define ALU_MOVE 5'd17
|
233 |
|
|
`define ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ 5'd18
|
234 |
|
|
`define ALU_CHK 5'd19
|
235 |
|
|
`define ALU_MULS_MULU_DIVS_DIVU 5'd20
|
236 |
|
|
`define ALU_BCHG_BCLR_BSET_BTST 5'd21
|
237 |
|
|
`define ALU_TAS 5'd22
|
238 |
|
|
`define ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT 5'd23
|
239 |
|
|
`define ALU_SIMPLE_LONG_ADD 5'd24
|
240 |
|
|
`define ALU_SIMPLE_LONG_SUB 5'd25
|
241 |
|
|
`define ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR 5'd26
|
242 |
|
|
`define ALU_SIMPLE_MOVE 5'd27
|
243 |
|
|
`define ALU_LINK_MOVE 5'd28
|
244 |
12 |
alfik |
|
245 |
|
|
`define BRANCH_IDLE 4'd0
|
246 |
|
|
`define BRANCH_movem_loop 4'd1 // BRANCH(movem_loop == 4'b1000)
|
247 |
|
|
`define BRANCH_movem_reg 4'd2 // BRANCH(movem_reg[0] == 0)
|
248 |
|
|
`define BRANCH_operand2 4'd3 // BRANCH(operand2[5:0] == 6'b0)
|
249 |
13 |
alfik |
`define BRANCH_alu_signal 4'd4 // BRANCH(alu_signal == 1'b0)
|
250 |
|
|
`define BRANCH_alu_mult_div_ready 4'd5 // BRANCH(alu_mult_div_ready == 1'b1)
|
251 |
12 |
alfik |
`define BRANCH_condition_0 4'd6 // BRANCH(condition == 1'b0)
|
252 |
|
|
`define BRANCH_condition_1 4'd7 // BRANCH(condition == 1'b1)
|
253 |
|
|
`define BRANCH_result 4'd8 // BRANCH(result[15:0] == 16'hFFFF)
|
254 |
|
|
`define BRANCH_V 4'd9 // BRANCH(V == 1'b0)
|
255 |
|
|
`define BRANCH_movep_16 4'd10 // BRANCH(ir[6] == 0)
|
256 |
|
|
`define BRANCH_stop_flag_wait_ir_decode 4'd11 // BRANCH(stop_flag == 1'b1) if no branch: wait for prefetch ir valid and decode instruction
|
257 |
|
|
`define BRANCH_ir 4'd12 // BRANCH(ir[7:0] != 8'b0)
|
258 |
|
|
`define BRANCH_trace_flag_and_interrupt 4'd13 // BRANCH(trace_flag == 1'b0 && interrupt_mask != 3'b000) if no branch: jump to main loop
|
259 |
|
|
`define BRANCH_group_0_flag 4'd14 // BRANCH(group_0_flag == 0)
|
260 |
|
|
`define BRANCH_procedure 4'd15 // call procedure, return from procedure
|
261 |
|
|
|
262 |
|
|
`define PROCEDURE_IDLE 4'd0
|
263 |
|
|
`define PROCEDURE_call_load_ea 4'd1 // load ea
|
264 |
|
|
`define PROCEDURE_call_perform_ea_read 4'd2 // perform_ea_read
|
265 |
|
|
`define PROCEDURE_call_perform_ea_write 4'd3 // perform_ea_write
|
266 |
|
|
`define PROCEDURE_call_save_ea 4'd4 // save ea
|
267 |
|
|
`define PROCEDURE_return 4'd5 // return from procedure
|
268 |
|
|
`define PROCEDURE_wait_finished 4'd6 // wait for finished signal from bus controler
|
269 |
|
|
`define PROCEDURE_wait_prefetch_valid 4'd7 // wait for prefetch ir valid, 64 bits
|
270 |
|
|
`define PROCEDURE_wait_prefetch_valid_32 4'd8 // wait for prefetch ir valid, 32 bits
|
271 |
|
|
`define PROCEDURE_jump_to_main_loop 4'd9 // jump to main loop
|
272 |
|
|
`define PROCEDURE_push_micropc 4'd10 // save current micro_pc
|
273 |
|
|
`define PROCEDURE_call_trap 4'd11 // call trap service procedure
|
274 |
|
|
`define PROCEDURE_pop_micropc 4'd12 // pop most recent micro_pc and forget
|
275 |
|
|
`define PROCEDURE_interrupt_mask 4'd13 // if interrupt active continue, else jump to main loop
|
276 |
|
|
`define PROCEDURE_call_read 4'd14 // load_ea + perform_ea_read
|
277 |
|
|
`define PROCEDURE_call_write 4'd15 // perform_ea_write + save_ea + return
|
278 |
|
|
// OPERATIONS END
|
279 |
|
|
|
280 |
|
|
/***********************************************************************************************************************
|
281 |
|
|
* Automatically generated by ao68000_tool microcode word bit assignments and addresses
|
282 |
|
|
**********************************************************************************************************************/
|
283 |
|
|
// MICROCODE - DO NOT EDIT BELOW
|
284 |
|
|
`define MICRO_DATA_ea_reg micro_data[2:0]
|
285 |
|
|
`define MICRO_DATA_ea_mod micro_data[6:3]
|
286 |
|
|
`define MICRO_DATA_ea_type micro_data[10:7]
|
287 |
|
|
`define MICRO_DATA_op1 micro_data[14:11]
|
288 |
|
|
`define MICRO_DATA_op2 micro_data[17:15]
|
289 |
|
|
`define MICRO_DATA_address micro_data[21:18]
|
290 |
|
|
`define MICRO_DATA_size micro_data[25:22]
|
291 |
|
|
`define MICRO_DATA_movem_modreg micro_data[28:26]
|
292 |
|
|
`define MICRO_DATA_movem_loop micro_data[30:29]
|
293 |
|
|
`define MICRO_DATA_movem_reg micro_data[32:31]
|
294 |
|
|
`define MICRO_DATA_ir micro_data[34:33]
|
295 |
|
|
`define MICRO_DATA_pc micro_data[37:35]
|
296 |
|
|
`define MICRO_DATA_trap micro_data[41:38]
|
297 |
|
|
`define MICRO_DATA_offset micro_data[43:42]
|
298 |
|
|
`define MICRO_DATA_index micro_data[45:44]
|
299 |
|
|
`define MICRO_DATA_stop_flag micro_data[47:46]
|
300 |
|
|
`define MICRO_DATA_trace_flag micro_data[49:48]
|
301 |
|
|
`define MICRO_DATA_group_0_flag micro_data[51:50]
|
302 |
|
|
`define MICRO_DATA_instruction_flag micro_data[53:52]
|
303 |
|
|
`define MICRO_DATA_read_modify_write_flag micro_data[55:54]
|
304 |
|
|
`define MICRO_DATA_do_reset_flag micro_data[57:56]
|
305 |
|
|
`define MICRO_DATA_do_interrupt_flag micro_data[59:58]
|
306 |
|
|
`define MICRO_DATA_do_read_flag micro_data[61:60]
|
307 |
|
|
`define MICRO_DATA_do_write_flag micro_data[63:62]
|
308 |
|
|
`define MICRO_DATA_do_blocked_flag micro_data[65:64]
|
309 |
|
|
`define MICRO_DATA_data_write micro_data[67:66]
|
310 |
|
|
`define MICRO_DATA_an_address micro_data[69:68]
|
311 |
|
|
`define MICRO_DATA_an_write_enable micro_data[70:70]
|
312 |
|
|
`define MICRO_DATA_an_input micro_data[72:71]
|
313 |
|
|
`define MICRO_DATA_dn_address micro_data[73:73]
|
314 |
|
|
`define MICRO_DATA_dn_write_enable micro_data[74:74]
|
315 |
|
|
`define MICRO_DATA_alu micro_data[79:75]
|
316 |
|
|
`define MICRO_DATA_branch micro_data[83:80]
|
317 |
|
|
`define MICRO_DATA_procedure micro_data[87:84]
|
318 |
|
|
|
319 |
17 |
alfik |
`define MICROPC_MOVE 9'd232
|
320 |
|
|
`define MICROPC_MOVE_USP_to_An 9'd401
|
321 |
|
|
`define MICROPC_TAS 9'd333
|
322 |
|
|
`define MICROPC_BSR 9'd431
|
323 |
12 |
alfik |
`define MICROPC_ADDRESS_BUS_TRAP 9'd3
|
324 |
|
|
`define MICROPC_MOVEP_register_to_memory 9'd106
|
325 |
17 |
alfik |
`define MICROPC_NEGX_CLR_NEG_NOT_NBCD 9'd338
|
326 |
|
|
`define MICROPC_RTS 9'd472
|
327 |
12 |
alfik |
`define MICROPC_MAIN_LOOP 9'd53
|
328 |
17 |
alfik |
`define MICROPC_ADDA_SUBA 9'd269
|
329 |
|
|
`define MICROPC_MOVE_TO_CCR_MOVE_TO_SR 9'd392
|
330 |
|
|
`define MICROPC_MOVE_FROM_SR 9'd389
|
331 |
12 |
alfik |
`define MICROPC_LOAD_EA_d8_PC_Xn 9'd79
|
332 |
|
|
`define MICROPC_TRAP_ENTRY 9'd35
|
333 |
|
|
`define MICROPC_PERFORM_EA_READ_memory 9'd89
|
334 |
17 |
alfik |
`define MICROPC_RESET 9'd486
|
335 |
12 |
alfik |
`define MICROPC_PERFORM_EA_WRITE_Dn 9'd91
|
336 |
17 |
alfik |
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory 9'd226
|
337 |
|
|
`define MICROPC_MOVEA 9'd240
|
338 |
|
|
`define MICROPC_TST 9'd345
|
339 |
|
|
`define MICROPC_BTST_register 9'd327
|
340 |
12 |
alfik |
`define MICROPC_LOAD_EA_d8_An_Xn 9'd68
|
341 |
17 |
alfik |
`define MICROPC_MULS_MULU_DIVS_DIVU 9'd291
|
342 |
|
|
`define MICROPC_MOVEQ 9'd308
|
343 |
|
|
`define MICROPC_CMPA 9'd276
|
344 |
|
|
`define MICROPC_EOR 9'd246
|
345 |
12 |
alfik |
`define MICROPC_LOAD_EA_xxx_W 9'd72
|
346 |
17 |
alfik |
`define MICROPC_DBcc 9'd375
|
347 |
12 |
alfik |
`define MICROPC_CMPI 9'd184
|
348 |
|
|
`define MICROPC_LOAD_EA_xxx_L 9'd74
|
349 |
17 |
alfik |
`define MICROPC_CMPM 9'd206
|
350 |
|
|
`define MICROPC_MOVE_USP_to_USP 9'd396
|
351 |
|
|
`define MICROPC_ADDQ_SUBQ_not_An 9'd349
|
352 |
|
|
`define MICROPC_ULNK 9'd420
|
353 |
|
|
`define MICROPC_EXG 9'd198
|
354 |
|
|
`define MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem 9'd251
|
355 |
|
|
`define MICROPC_Bcc_BRA 9'd363
|
356 |
12 |
alfik |
`define MICROPC_PERFORM_EA_READ_An 9'd86
|
357 |
|
|
`define MICROPC_LOAD_EA_d16_PC 9'd76
|
358 |
17 |
alfik |
`define MICROPC_NOP 9'd480
|
359 |
12 |
alfik |
`define MICROPC_MOVEM_register_to_memory_predecrement 9'd131
|
360 |
17 |
alfik |
`define MICROPC_RTE_RTR 9'd460
|
361 |
|
|
`define MICROPC_TRAP 9'd481
|
362 |
|
|
`define MICROPC_ADDQ_SUBQ_An 9'd352
|
363 |
12 |
alfik |
`define MICROPC_MOVEM_register_to_memory_control 9'd147
|
364 |
17 |
alfik |
`define MICROPC_BTST_immediate 9'd316
|
365 |
12 |
alfik |
`define MICROPC_MOVEP_memory_to_register 9'd98
|
366 |
|
|
`define MICROPC_PERFORM_EA_WRITE_An 9'd92
|
367 |
17 |
alfik |
`define MICROPC_CHK 9'd282
|
368 |
|
|
`define MICROPC_Scc 9'd356
|
369 |
|
|
`define MICROPC_JMP 9'd443
|
370 |
12 |
alfik |
`define MICROPC_PEA 9'd168
|
371 |
|
|
`define MICROPC_SAVE_EA_minus_An 9'd97
|
372 |
|
|
`define MICROPC_ANDI_EORI_ORI_ADDI_SUBI 9'd174
|
373 |
17 |
alfik |
`define MICROPC_BCHG_BCLR_BSET_immediate 9'd311
|
374 |
12 |
alfik |
`define MICROPC_LOAD_EA_An 9'd62
|
375 |
|
|
`define MICROPC_PERFORM_EA_READ_imm 9'd87
|
376 |
17 |
alfik |
`define MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn 9'd256
|
377 |
12 |
alfik |
`define MICROPC_LEA 9'd162
|
378 |
17 |
alfik |
`define MICROPC_TRAPV 9'd483
|
379 |
|
|
`define MICROPC_LINK 9'd404
|
380 |
12 |
alfik |
`define MICROPC_ABCD_SBCD_ADDX_SUBX 9'd189
|
381 |
17 |
alfik |
`define MICROPC_BCHG_BCLR_BSET_register 9'd322
|
382 |
12 |
alfik |
`define MICROPC_PERFORM_EA_READ_Dn 9'd85
|
383 |
|
|
`define MICROPC_LOAD_EA_illegal_command 9'd83
|
384 |
|
|
`define MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR 9'd178
|
385 |
17 |
alfik |
`define MICROPC_CMP 9'd263
|
386 |
|
|
`define MICROPC_SWAP_EXT 9'd341
|
387 |
|
|
`define MICROPC_STOP 9'd489
|
388 |
12 |
alfik |
`define MICROPC_PERFORM_EA_WRITE_memory 9'd93
|
389 |
17 |
alfik |
`define MICROPC_JSR 9'd451
|
390 |
12 |
alfik |
`define MICROPC_LOAD_EA_minus_An 9'd63
|
391 |
17 |
alfik |
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register 9'd213
|
392 |
12 |
alfik |
`define MICROPC_SAVE_EA_An_plus 9'd95
|
393 |
|
|
`define MICROPC_LOAD_EA_d16_An 9'd65
|
394 |
|
|
`define MICROPC_LOAD_EA_An_plus 9'd62
|
395 |
|
|
`define MICROPC_MOVEM_memory_to_register 9'd116
|
396 |
|
|
// MICROCODE - DO NOT EDIT ABOVE
|
397 |
|
|
|
398 |
|
|
/***********************************************************************************************************************
|
399 |
|
|
* ao68000 top level module
|
400 |
|
|
**********************************************************************************************************************/
|
401 |
|
|
|
402 |
|
|
/*! \brief ao68000 top level module.
|
403 |
|
|
*
|
404 |
|
|
* This module contains only instantiations of sub-modules and wire declarations.
|
405 |
|
|
*/
|
406 |
|
|
module ao68000 (
|
407 |
|
|
//****************** WISHBONE
|
408 |
|
|
input CLK_I, //% \copydoc CLK_I
|
409 |
|
|
input reset_n, //% \copydoc reset_n
|
410 |
|
|
|
411 |
|
|
output CYC_O, //% \copydoc CYC_O
|
412 |
|
|
output [31:2] ADR_O, //% \copydoc ADR_O
|
413 |
|
|
output [31:0] DAT_O, //% \copydoc DAT_O
|
414 |
|
|
input [31:0] DAT_I, //% \copydoc DAT_I
|
415 |
|
|
output [3:0] SEL_O, //% \copydoc SEL_O
|
416 |
|
|
output STB_O, //% \copydoc STB_O
|
417 |
|
|
output WE_O, //% \copydoc WE_O
|
418 |
|
|
|
419 |
|
|
input ACK_I, //% \copydoc ACK_I
|
420 |
|
|
input ERR_I, //% \copydoc ERR_I
|
421 |
|
|
input RTY_I, //% \copydoc RTY_I
|
422 |
|
|
|
423 |
|
|
// TAG_TYPE: TGC_O
|
424 |
|
|
output SGL_O, //% \copydoc SGL_O
|
425 |
|
|
output BLK_O, //% \copydoc BLK_O
|
426 |
|
|
output RMW_O, //% \copydoc RMW_O
|
427 |
|
|
|
428 |
|
|
// TAG_TYPE: TGA_O
|
429 |
|
|
output [2:0] CTI_O, //% \copydoc CTI_O
|
430 |
|
|
output [1:0] BTE_O, //% \copydoc BTE_O
|
431 |
|
|
|
432 |
|
|
// TAG_TYPE: TGC_O
|
433 |
|
|
output [2:0] fc_o, //% \copydoc fc_o
|
434 |
|
|
|
435 |
|
|
//****************** OTHER
|
436 |
|
|
/* interrupt acknowlege:
|
437 |
|
|
* ACK_I: interrupt vector on DAT_I[7:0]
|
438 |
|
|
* ERR_I: spurious interrupt
|
439 |
|
|
* RTY_I: autovector
|
440 |
|
|
*/
|
441 |
|
|
input [2:0] ipl_i, //% \copydoc ipl_i
|
442 |
|
|
output reset_o, //% \copydoc reset_o
|
443 |
|
|
output blocked_o //% \copydoc blocked_o
|
444 |
|
|
);
|
445 |
|
|
|
446 |
|
|
wire [15:0] sr;
|
447 |
13 |
alfik |
wire [2:0] size;
|
448 |
12 |
alfik |
wire [31:0] address;
|
449 |
|
|
wire address_type;
|
450 |
|
|
wire read_modify_write_flag;
|
451 |
|
|
wire [31:0] data_read;
|
452 |
|
|
wire [31:0] data_write;
|
453 |
|
|
wire [31:0] pc;
|
454 |
|
|
wire prefetch_ir_valid;
|
455 |
|
|
wire [79:0] prefetch_ir;
|
456 |
|
|
wire do_reset;
|
457 |
|
|
wire do_read;
|
458 |
|
|
wire do_write;
|
459 |
|
|
wire do_interrupt;
|
460 |
|
|
wire do_blocked;
|
461 |
|
|
wire jmp_address_trap;
|
462 |
|
|
wire jmp_bus_trap;
|
463 |
|
|
wire finished;
|
464 |
|
|
wire [7:0] interrupt_trap;
|
465 |
|
|
wire [2:0] interrupt_mask;
|
466 |
|
|
wire rw_state;
|
467 |
|
|
wire [2:0] fc_state;
|
468 |
|
|
wire [7:0] decoder_trap;
|
469 |
|
|
wire [31:0] usp;
|
470 |
|
|
wire [31:0] Dn_output;
|
471 |
|
|
wire [31:0] An_output;
|
472 |
|
|
wire [31:0] result;
|
473 |
|
|
wire [3:0] An_address;
|
474 |
|
|
wire [31:0] An_input;
|
475 |
|
|
wire [2:0] Dn_address;
|
476 |
|
|
wire [15:0] ir;
|
477 |
|
|
wire [8:0] decoder_micropc;
|
478 |
13 |
alfik |
wire alu_signal;
|
479 |
|
|
wire alu_mult_div_ready;
|
480 |
12 |
alfik |
wire [8:0] load_ea;
|
481 |
|
|
wire [8:0] perform_ea_read;
|
482 |
|
|
wire [8:0] perform_ea_write;
|
483 |
|
|
wire [8:0] save_ea;
|
484 |
|
|
wire trace_flag;
|
485 |
|
|
wire group_0_flag;
|
486 |
|
|
wire stop_flag;
|
487 |
|
|
wire [8:0] micro_pc;
|
488 |
|
|
wire [31:0] operand1;
|
489 |
|
|
wire [31:0] operand2;
|
490 |
|
|
wire [4:0] movem_loop;
|
491 |
|
|
wire [15:0] movem_reg;
|
492 |
|
|
wire condition;
|
493 |
|
|
wire [87:0] micro_data;
|
494 |
|
|
wire [31:0] fault_address_state;
|
495 |
|
|
wire [1:0] pc_change;
|
496 |
|
|
wire prefetch_ir_valid_32;
|
497 |
|
|
wire [3:0] ea_type;
|
498 |
|
|
wire [2:0] ea_mod;
|
499 |
|
|
wire [2:0] ea_reg;
|
500 |
16 |
alfik |
wire [17:0] decoder_alu;
|
501 |
|
|
wire [17:0] decoder_alu_reg;
|
502 |
12 |
alfik |
|
503 |
|
|
bus_control bus_control_m(
|
504 |
|
|
.CLK_I (CLK_I),
|
505 |
|
|
.reset_n (reset_n),
|
506 |
|
|
.CYC_O (CYC_O),
|
507 |
|
|
.ADR_O (ADR_O),
|
508 |
|
|
.DAT_O (DAT_O),
|
509 |
|
|
.DAT_I (DAT_I),
|
510 |
|
|
.SEL_O (SEL_O),
|
511 |
|
|
.STB_O (STB_O),
|
512 |
|
|
.WE_O (WE_O),
|
513 |
|
|
.ACK_I (ACK_I),
|
514 |
|
|
.ERR_I (ERR_I),
|
515 |
|
|
.RTY_I (RTY_I),
|
516 |
|
|
.SGL_O (SGL_O),
|
517 |
|
|
.BLK_O (BLK_O),
|
518 |
|
|
.RMW_O (RMW_O),
|
519 |
|
|
.CTI_O (CTI_O),
|
520 |
|
|
.BTE_O (BTE_O),
|
521 |
|
|
.fc_o (fc_o),
|
522 |
|
|
.ipl_i (ipl_i),
|
523 |
|
|
.reset_o (reset_o),
|
524 |
|
|
.blocked_o (blocked_o),
|
525 |
|
|
|
526 |
|
|
.supervisor_i (sr[13]),
|
527 |
|
|
.ipm_i (sr[10:8]),
|
528 |
|
|
.size_i (size),
|
529 |
|
|
.address_i (address),
|
530 |
|
|
.address_type_i (address_type),
|
531 |
|
|
.read_modify_write_i (read_modify_write_flag),
|
532 |
|
|
.data_write_i (data_write),
|
533 |
|
|
.data_read_o (data_read),
|
534 |
|
|
.pc_i (pc),
|
535 |
|
|
.pc_change_i (pc_change),
|
536 |
|
|
.prefetch_ir_o (prefetch_ir),
|
537 |
|
|
.prefetch_ir_valid_32_o (prefetch_ir_valid_32),
|
538 |
|
|
.prefetch_ir_valid_o (prefetch_ir_valid),
|
539 |
|
|
.prefetch_ir_valid_80_o (),
|
540 |
|
|
.do_reset_i (do_reset),
|
541 |
|
|
.do_blocked_i (do_blocked),
|
542 |
|
|
.do_read_i (do_read),
|
543 |
|
|
.do_write_i (do_write),
|
544 |
|
|
.do_interrupt_i (do_interrupt),
|
545 |
|
|
.jmp_address_trap_o (jmp_address_trap),
|
546 |
|
|
.jmp_bus_trap_o (jmp_bus_trap),
|
547 |
|
|
.finished_o (finished),
|
548 |
|
|
.interrupt_trap_o (interrupt_trap),
|
549 |
|
|
.interrupt_mask_o (interrupt_mask),
|
550 |
|
|
.rw_state_o (rw_state),
|
551 |
|
|
.fc_state_o (fc_state),
|
552 |
|
|
.fault_address_state_o (fault_address_state)
|
553 |
|
|
);
|
554 |
|
|
|
555 |
|
|
registers registers_m(
|
556 |
|
|
.clock (CLK_I),
|
557 |
|
|
.reset_n (reset_n),
|
558 |
|
|
.data_read (data_read),
|
559 |
|
|
.prefetch_ir (prefetch_ir),
|
560 |
|
|
.prefetch_ir_valid (prefetch_ir_valid),
|
561 |
|
|
.result (result),
|
562 |
|
|
.sr (sr),
|
563 |
|
|
.rw_state (rw_state),
|
564 |
|
|
.fc_state (fc_state),
|
565 |
|
|
.fault_address_state (fault_address_state),
|
566 |
|
|
.interrupt_trap (interrupt_trap),
|
567 |
|
|
.interrupt_mask (interrupt_mask),
|
568 |
|
|
.decoder_trap (decoder_trap),
|
569 |
|
|
.usp (usp),
|
570 |
|
|
.Dn_output (Dn_output),
|
571 |
|
|
.An_output (An_output),
|
572 |
|
|
|
573 |
|
|
.pc_change (pc_change),
|
574 |
|
|
|
575 |
|
|
.ea_reg (ea_reg),
|
576 |
|
|
.ea_reg_control (`MICRO_DATA_ea_reg),
|
577 |
|
|
.ea_mod (ea_mod),
|
578 |
|
|
.ea_mod_control (`MICRO_DATA_ea_mod),
|
579 |
|
|
.ea_type (ea_type),
|
580 |
|
|
.ea_type_control (`MICRO_DATA_ea_type),
|
581 |
|
|
.operand1 (operand1),
|
582 |
|
|
.operand1_control (`MICRO_DATA_op1),
|
583 |
|
|
.operand2 (operand2),
|
584 |
|
|
.operand2_control (`MICRO_DATA_op2),
|
585 |
|
|
.address (address),
|
586 |
|
|
.address_type (address_type),
|
587 |
|
|
.address_control (`MICRO_DATA_address),
|
588 |
|
|
.size (size),
|
589 |
|
|
.size_control (`MICRO_DATA_size),
|
590 |
|
|
.movem_modreg (),
|
591 |
|
|
.movem_modreg_control (`MICRO_DATA_movem_modreg),
|
592 |
|
|
.movem_loop (movem_loop),
|
593 |
|
|
.movem_loop_control (`MICRO_DATA_movem_loop),
|
594 |
|
|
.movem_reg (movem_reg),
|
595 |
|
|
.movem_reg_control (`MICRO_DATA_movem_reg),
|
596 |
|
|
.ir (ir),
|
597 |
|
|
.ir_control (`MICRO_DATA_ir),
|
598 |
|
|
.pc (pc),
|
599 |
|
|
.pc_control (`MICRO_DATA_pc),
|
600 |
|
|
.trap (),
|
601 |
|
|
.trap_control (`MICRO_DATA_trap),
|
602 |
|
|
.offset (),
|
603 |
|
|
.offset_control (`MICRO_DATA_offset),
|
604 |
|
|
.index (),
|
605 |
|
|
.index_control (`MICRO_DATA_index),
|
606 |
|
|
.stop_flag (stop_flag),
|
607 |
|
|
.stop_flag_control (`MICRO_DATA_stop_flag),
|
608 |
|
|
.trace_flag (trace_flag),
|
609 |
|
|
.trace_flag_control (`MICRO_DATA_trace_flag),
|
610 |
|
|
.group_0_flag (group_0_flag),
|
611 |
|
|
.group_0_flag_control (`MICRO_DATA_group_0_flag),
|
612 |
|
|
.instruction_flag (),
|
613 |
|
|
.instruction_flag_control (`MICRO_DATA_instruction_flag),
|
614 |
|
|
.read_modify_write_flag (read_modify_write_flag),
|
615 |
|
|
.read_modify_write_flag_control (`MICRO_DATA_read_modify_write_flag),
|
616 |
|
|
.do_reset_flag (do_reset),
|
617 |
|
|
.do_reset_flag_control (`MICRO_DATA_do_reset_flag),
|
618 |
|
|
.do_interrupt_flag (do_interrupt),
|
619 |
|
|
.do_interrupt_flag_control (`MICRO_DATA_do_interrupt_flag),
|
620 |
|
|
.do_read_flag (do_read),
|
621 |
|
|
.do_read_flag_control (`MICRO_DATA_do_read_flag),
|
622 |
|
|
.do_write_flag (do_write),
|
623 |
|
|
.do_write_flag_control (`MICRO_DATA_do_write_flag),
|
624 |
|
|
.do_blocked_flag (do_blocked),
|
625 |
|
|
.do_blocked_flag_control (`MICRO_DATA_do_blocked_flag),
|
626 |
|
|
.data_write (data_write),
|
627 |
|
|
.data_write_control (`MICRO_DATA_data_write),
|
628 |
|
|
.An_address (An_address),
|
629 |
|
|
.An_address_control (`MICRO_DATA_an_address),
|
630 |
|
|
.An_input (An_input),
|
631 |
|
|
.An_input_control (`MICRO_DATA_an_input),
|
632 |
|
|
.Dn_address (Dn_address),
|
633 |
16 |
alfik |
.Dn_address_control (`MICRO_DATA_dn_address),
|
634 |
|
|
.decoder_alu (decoder_alu),
|
635 |
|
|
.decoder_alu_reg (decoder_alu_reg)
|
636 |
12 |
alfik |
);
|
637 |
|
|
|
638 |
|
|
memory_registers memory_registers_m(
|
639 |
|
|
.clock (CLK_I),
|
640 |
|
|
.reset_n (reset_n),
|
641 |
|
|
.An_address (An_address),
|
642 |
|
|
.An_input (An_input),
|
643 |
|
|
.An_write_enable (`MICRO_DATA_an_write_enable),
|
644 |
|
|
.An_output (An_output),
|
645 |
|
|
.usp (usp),
|
646 |
|
|
.Dn_address (Dn_address),
|
647 |
|
|
.Dn_input (result),
|
648 |
|
|
.Dn_write_enable (`MICRO_DATA_dn_write_enable),
|
649 |
|
|
.Dn_size (size),
|
650 |
|
|
.Dn_output (Dn_output),
|
651 |
|
|
.micro_pc (micro_pc),
|
652 |
|
|
.micro_data (micro_data)
|
653 |
|
|
);
|
654 |
|
|
|
655 |
|
|
decoder decoder_m(
|
656 |
|
|
.clock (CLK_I),
|
657 |
|
|
.reset_n (reset_n),
|
658 |
|
|
.supervisor (sr[13]),
|
659 |
|
|
.ir (prefetch_ir[79:64]),
|
660 |
|
|
.decoder_trap (decoder_trap),
|
661 |
|
|
.decoder_micropc (decoder_micropc),
|
662 |
16 |
alfik |
.decoder_alu (decoder_alu),
|
663 |
12 |
alfik |
|
664 |
|
|
.load_ea (load_ea),
|
665 |
|
|
.perform_ea_read (perform_ea_read),
|
666 |
|
|
.perform_ea_write (perform_ea_write),
|
667 |
|
|
.save_ea (save_ea),
|
668 |
|
|
|
669 |
|
|
.ea_type (ea_type),
|
670 |
|
|
.ea_mod (ea_mod),
|
671 |
|
|
.ea_reg (ea_reg)
|
672 |
|
|
);
|
673 |
|
|
|
674 |
|
|
condition condition_m(
|
675 |
|
|
.cond (ir[11:8]),
|
676 |
|
|
.ccr (sr[7:0]),
|
677 |
|
|
.condition (condition)
|
678 |
|
|
);
|
679 |
|
|
|
680 |
|
|
alu alu_m(
|
681 |
|
|
.clock (CLK_I),
|
682 |
|
|
.reset_n (reset_n),
|
683 |
|
|
.address (address),
|
684 |
|
|
.ir (ir),
|
685 |
|
|
.size (size),
|
686 |
|
|
.operand1 (operand1),
|
687 |
|
|
.operand2 (operand2),
|
688 |
|
|
.interrupt_mask (interrupt_mask),
|
689 |
|
|
.alu_control (`MICRO_DATA_alu),
|
690 |
|
|
.sr (sr),
|
691 |
|
|
.result (result),
|
692 |
13 |
alfik |
.alu_signal (alu_signal),
|
693 |
16 |
alfik |
.alu_mult_div_ready (alu_mult_div_ready),
|
694 |
|
|
.decoder_alu_reg (decoder_alu_reg)
|
695 |
12 |
alfik |
);
|
696 |
|
|
|
697 |
|
|
microcode_branch microcode_branch_m(
|
698 |
|
|
.clock (CLK_I),
|
699 |
|
|
.reset_n (reset_n),
|
700 |
|
|
.movem_loop (movem_loop),
|
701 |
|
|
.movem_reg (movem_reg),
|
702 |
|
|
.operand2 (operand2),
|
703 |
13 |
alfik |
.alu_signal (alu_signal),
|
704 |
|
|
.alu_mult_div_ready (alu_mult_div_ready),
|
705 |
12 |
alfik |
.condition (condition),
|
706 |
|
|
.result (result),
|
707 |
|
|
.overflow (sr[1]),
|
708 |
|
|
.stop_flag (stop_flag),
|
709 |
|
|
.ir (ir),
|
710 |
|
|
.decoder_trap (decoder_trap),
|
711 |
|
|
.trace_flag (trace_flag),
|
712 |
|
|
.group_0_flag (group_0_flag),
|
713 |
|
|
.interrupt_mask (interrupt_mask),
|
714 |
|
|
.load_ea (load_ea),
|
715 |
|
|
.perform_ea_read (perform_ea_read),
|
716 |
|
|
.perform_ea_write (perform_ea_write),
|
717 |
|
|
.save_ea (save_ea),
|
718 |
|
|
.decoder_micropc (decoder_micropc),
|
719 |
|
|
.prefetch_ir_valid_32 (prefetch_ir_valid_32),
|
720 |
|
|
.prefetch_ir_valid (prefetch_ir_valid),
|
721 |
|
|
.jmp_address_trap (jmp_address_trap),
|
722 |
|
|
.jmp_bus_trap (jmp_bus_trap),
|
723 |
|
|
.finished (finished),
|
724 |
|
|
.branch_control (`MICRO_DATA_branch),
|
725 |
|
|
.branch_offset (`MICRO_DATA_procedure),
|
726 |
|
|
.micro_pc (micro_pc)
|
727 |
|
|
);
|
728 |
|
|
|
729 |
|
|
endmodule
|
730 |
|
|
|
731 |
|
|
/***********************************************************************************************************************
|
732 |
|
|
* Bus control
|
733 |
|
|
**********************************************************************************************************************/
|
734 |
|
|
|
735 |
|
|
/*! \brief Initiate WISHBONE MASTER bus cycles.
|
736 |
|
|
*
|
737 |
|
|
* The bus_control module is the only module that has contact with signals from outside of the IP core.
|
738 |
|
|
* It is responsible for initiating WISHBONE MASTER bus cycles. The cycles can be divided into:
|
739 |
|
|
* - memory read cycles (supervisor data, supervisor program, user data, user program)
|
740 |
|
|
* - memory write cycles (supervisor data, user data),
|
741 |
|
|
* - interrupt acknowledge.
|
742 |
|
|
*
|
743 |
|
|
* Every cycle is supplemented with the following tags:
|
744 |
|
|
* - standard WISHBONE cycle tags: SGL_O, BLK_O, RMW_O,
|
745 |
|
|
* - register feedback WISHBONE address tags: CTI_O and BTE_O,
|
746 |
|
|
* - ao68000 specific cycle tag: fc_o which is equivalent to MC68000 function codes.
|
747 |
|
|
*
|
748 |
|
|
* The bus_control module is also responsible for registering interrupt inputs and initiating the interrupt acknowledge
|
749 |
|
|
* cycle in response to a microcode request. Microcode requests a interrupt acknowledge at the end of instruction
|
750 |
|
|
* processing, when the interrupt privilege level is higher than the current interrupt privilege mask, as specified
|
751 |
|
|
* in the MC68000 User's Manual.
|
752 |
|
|
*
|
753 |
|
|
* Finally, bus_control controls also two ao68000 specific core outputs:
|
754 |
|
|
* - blocked output, high when that the processor is blocked after encountering a double bus error. The only way
|
755 |
|
|
* to leave this block state is by reseting the ao68000 by the asynchronous reset input signal.
|
756 |
|
|
* - reset output, high when processing the RESET instruction. Can be used to reset external devices.
|
757 |
|
|
*/
|
758 |
|
|
module bus_control(
|
759 |
|
|
//******************************************* external
|
760 |
|
|
//****************** WISHBONE
|
761 |
|
|
input CLK_I,
|
762 |
|
|
input reset_n,
|
763 |
|
|
|
764 |
|
|
output reg CYC_O,
|
765 |
|
|
output reg [31:2] ADR_O,
|
766 |
|
|
output reg [31:0] DAT_O,
|
767 |
|
|
input [31:0] DAT_I,
|
768 |
|
|
output reg [3:0] SEL_O,
|
769 |
|
|
output reg STB_O,
|
770 |
|
|
output reg WE_O,
|
771 |
|
|
|
772 |
|
|
input ACK_I,
|
773 |
|
|
input ERR_I,
|
774 |
|
|
input RTY_I,
|
775 |
|
|
|
776 |
|
|
// TAG_TYPE: TGC_O
|
777 |
|
|
output reg SGL_O,
|
778 |
|
|
output reg BLK_O,
|
779 |
|
|
output reg RMW_O,
|
780 |
|
|
|
781 |
|
|
// TAG_TYPE: TGA_O
|
782 |
|
|
output reg [2:0] CTI_O,
|
783 |
|
|
output [1:0] BTE_O,
|
784 |
|
|
|
785 |
|
|
// TAG_TYPE: TGC_O
|
786 |
|
|
output reg [2:0] fc_o,
|
787 |
|
|
|
788 |
|
|
//****************** OTHER
|
789 |
|
|
input [2:0] ipl_i,
|
790 |
|
|
output reg reset_o = 1'b0,
|
791 |
|
|
output reg blocked_o = 1'b0,
|
792 |
|
|
|
793 |
|
|
//******************************************* internal
|
794 |
|
|
input supervisor_i,
|
795 |
|
|
input [2:0] ipm_i,
|
796 |
13 |
alfik |
input [2:0] size_i,
|
797 |
12 |
alfik |
input [31:0] address_i,
|
798 |
|
|
input address_type_i,
|
799 |
|
|
input read_modify_write_i,
|
800 |
|
|
input [31:0] data_write_i,
|
801 |
|
|
output reg [31:0] data_read_o,
|
802 |
|
|
|
803 |
|
|
input [31:0] pc_i,
|
804 |
|
|
input [1:0] pc_change_i,
|
805 |
|
|
output reg [79:0] prefetch_ir_o,
|
806 |
|
|
output reg prefetch_ir_valid_32_o = 1'b0,
|
807 |
|
|
output reg prefetch_ir_valid_o = 1'b0,
|
808 |
|
|
output reg prefetch_ir_valid_80_o = 1'b0,
|
809 |
|
|
|
810 |
|
|
input do_reset_i,
|
811 |
|
|
input do_blocked_i,
|
812 |
|
|
input do_read_i,
|
813 |
|
|
input do_write_i,
|
814 |
|
|
input do_interrupt_i,
|
815 |
|
|
|
816 |
|
|
output reg jmp_address_trap_o = 1'b0,
|
817 |
|
|
output reg jmp_bus_trap_o = 1'b0,
|
818 |
|
|
// read/write/interrupt
|
819 |
|
|
output reg finished_o,
|
820 |
|
|
|
821 |
|
|
output reg [7:0] interrupt_trap_o = 8'b0,
|
822 |
|
|
output reg [2:0] interrupt_mask_o = 3'b0,
|
823 |
|
|
|
824 |
|
|
/* mask==0 && trap==0 nothing
|
825 |
|
|
* mask!=0 interrupt with spurious interrupt
|
826 |
|
|
*/
|
827 |
|
|
|
828 |
|
|
// write = 0/read = 1
|
829 |
|
|
output reg rw_state_o,
|
830 |
|
|
output reg [2:0] fc_state_o,
|
831 |
|
|
output reg [31:0] fault_address_state_o
|
832 |
|
|
);
|
833 |
|
|
|
834 |
|
|
assign BTE_O = 2'b00;
|
835 |
|
|
|
836 |
|
|
wire [31:0] pc_i_plus_6;
|
837 |
|
|
assign pc_i_plus_6 = pc_i + 32'd6;
|
838 |
|
|
wire [31:0] pc_i_plus_4;
|
839 |
|
|
assign pc_i_plus_4 = pc_i + 32'd4;
|
840 |
|
|
|
841 |
|
|
wire [31:0] address_i_plus_4;
|
842 |
|
|
assign address_i_plus_4 = address_i + 32'd4;
|
843 |
|
|
|
844 |
|
|
reg [1:0] saved_pc_change = 2'b00;
|
845 |
|
|
|
846 |
|
|
parameter [4:0]
|
847 |
|
|
S_INIT = 5'd0,
|
848 |
|
|
S_RESET = 5'd1,
|
849 |
|
|
S_BLOCKED = 5'd2,
|
850 |
|
|
S_INT_1 = 5'd3,
|
851 |
|
|
S_READ_1 = 5'd4,
|
852 |
|
|
S_READ_2 = 5'd5,
|
853 |
|
|
S_READ_3 = 5'd6,
|
854 |
|
|
S_WAIT = 5'd7,
|
855 |
|
|
S_WRITE_1 = 5'd8,
|
856 |
|
|
S_WRITE_2 = 5'd9,
|
857 |
|
|
S_WRITE_3 = 5'd10,
|
858 |
|
|
S_PC_0 = 5'd11,
|
859 |
|
|
S_PC_1 = 5'd12,
|
860 |
|
|
S_PC_2 = 5'd13,
|
861 |
|
|
S_PC_3 = 5'd14,
|
862 |
|
|
S_PC_4 = 5'd15,
|
863 |
|
|
S_PC_5 = 5'd16,
|
864 |
|
|
S_PC_6 = 5'd17;
|
865 |
|
|
|
866 |
|
|
parameter [2:0]
|
867 |
|
|
FC_USER_DATA = 3'd1,
|
868 |
|
|
FC_USER_PROGRAM = 3'd2,
|
869 |
|
|
FC_SUPERVISOR_DATA = 3'd5, // all exception vector entries except reset
|
870 |
|
|
FC_SUPERVISOR_PROGRAM = 3'd6, // exception vector for reset
|
871 |
|
|
FC_CPU_SPACE = 3'd7; // interrupt acknowlege bus cycle
|
872 |
|
|
|
873 |
|
|
parameter [2:0]
|
874 |
|
|
CTI_CLASSIC_CYCLE = 3'd0,
|
875 |
|
|
CTI_CONST_CYCLE = 3'd1,
|
876 |
|
|
CTI_INCR_CYCLE = 3'd2,
|
877 |
|
|
CTI_END_OF_BURST = 3'd7;
|
878 |
|
|
|
879 |
|
|
parameter [7:0]
|
880 |
|
|
VECTOR_BUS_TRAP = 8'd2,
|
881 |
|
|
VECTOR_ADDRESS_TRAP = 8'd3;
|
882 |
|
|
|
883 |
|
|
reg [4:0] current_state;
|
884 |
|
|
reg [7:0] reset_counter;
|
885 |
|
|
|
886 |
|
|
reg [2:0] last_interrupt_mask;
|
887 |
|
|
always @(posedge CLK_I or negedge reset_n) begin
|
888 |
|
|
if(reset_n == 1'b0) begin
|
889 |
|
|
interrupt_mask_o <= 3'b000;
|
890 |
|
|
last_interrupt_mask <= 3'b000;
|
891 |
|
|
end
|
892 |
|
|
else if(ipl_i > ipm_i && do_interrupt_i == 1'b0) begin
|
893 |
|
|
interrupt_mask_o <= ipl_i;
|
894 |
|
|
last_interrupt_mask <= interrupt_mask_o;
|
895 |
|
|
end
|
896 |
|
|
else if(do_interrupt_i == 1'b1) begin
|
897 |
|
|
interrupt_mask_o <= last_interrupt_mask;
|
898 |
|
|
end
|
899 |
|
|
else begin
|
900 |
|
|
interrupt_mask_o <= 3'b000;
|
901 |
|
|
last_interrupt_mask <= 3'b000;
|
902 |
|
|
end
|
903 |
|
|
end
|
904 |
|
|
|
905 |
|
|
// change pc_i in middle of prefetch operation: undefined
|
906 |
|
|
|
907 |
|
|
always @(posedge CLK_I or negedge reset_n) begin
|
908 |
|
|
if(reset_n == 1'b0) begin
|
909 |
|
|
current_state <= S_INIT;
|
910 |
|
|
interrupt_trap_o <= 8'd0;
|
911 |
|
|
prefetch_ir_valid_o <= 1'b0;
|
912 |
|
|
prefetch_ir_valid_32_o <= 1'b0;
|
913 |
|
|
prefetch_ir_valid_80_o <= 1'b0;
|
914 |
|
|
|
915 |
|
|
jmp_address_trap_o <= 1'b0;
|
916 |
|
|
jmp_bus_trap_o <= 1'b0;
|
917 |
|
|
|
918 |
|
|
CYC_O <= 1'b0;
|
919 |
|
|
ADR_O <= 30'd0;
|
920 |
|
|
DAT_O <= 32'd0;
|
921 |
|
|
SEL_O <= 4'b0;
|
922 |
|
|
STB_O <= 1'b0;
|
923 |
|
|
WE_O <= 1'b0;
|
924 |
|
|
SGL_O <= 1'b0;
|
925 |
|
|
BLK_O <= 1'b0;
|
926 |
|
|
RMW_O <= 1'b0;
|
927 |
|
|
CTI_O <= 3'd0;
|
928 |
|
|
fc_o <= 3'd0;
|
929 |
|
|
reset_o <= 1'b0;
|
930 |
|
|
blocked_o <= 1'b0;
|
931 |
|
|
data_read_o <= 32'd0;
|
932 |
|
|
finished_o <= 1'b0;
|
933 |
|
|
rw_state_o <= 1'b0;
|
934 |
|
|
fc_state_o <= 3'd0;
|
935 |
|
|
fault_address_state_o <= 32'd0;
|
936 |
|
|
saved_pc_change <= 2'b0;
|
937 |
|
|
reset_counter <= 8'd0;
|
938 |
|
|
end
|
939 |
|
|
else begin
|
940 |
|
|
case(current_state)
|
941 |
|
|
S_INIT: begin
|
942 |
|
|
finished_o <= 1'b0;
|
943 |
|
|
jmp_address_trap_o <= 1'b0;
|
944 |
|
|
jmp_bus_trap_o <= 1'b0;
|
945 |
|
|
reset_o <= 1'b0;
|
946 |
|
|
blocked_o <= 1'b0;
|
947 |
|
|
|
948 |
|
|
// block
|
949 |
|
|
if(do_blocked_i == 1'b1) begin
|
950 |
|
|
blocked_o <= 1'b1;
|
951 |
|
|
current_state <= S_BLOCKED;
|
952 |
|
|
end
|
953 |
|
|
// reset
|
954 |
|
|
else if(do_reset_i == 1'b1) begin
|
955 |
|
|
reset_o <= 1'b1;
|
956 |
|
|
reset_counter <= 8'd124;
|
957 |
|
|
current_state <= S_RESET;
|
958 |
|
|
end
|
959 |
|
|
// read
|
960 |
|
|
else if(do_read_i == 1'b1) begin
|
961 |
|
|
WE_O <= 1'b0;
|
962 |
|
|
if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
|
963 |
|
|
else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
|
964 |
|
|
|
965 |
13 |
alfik |
if(address_i[0] == 1'b1 && (size_i[0] == 1'b0)) begin // WORD or LONG WORD
|
966 |
12 |
alfik |
fault_address_state_o <= address_i;
|
967 |
|
|
rw_state_o <= 1'b1;
|
968 |
|
|
fc_state_o <= (supervisor_i == 1'b1) ? ((address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM) :
|
969 |
|
|
((address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM);
|
970 |
|
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
971 |
|
|
|
972 |
|
|
jmp_address_trap_o <= 1'b1;
|
973 |
|
|
current_state <= S_WAIT;
|
974 |
|
|
end
|
975 |
|
|
else begin
|
976 |
|
|
CYC_O <= 1'b1;
|
977 |
|
|
ADR_O <= address_i[31:2];
|
978 |
13 |
alfik |
SEL_O <= (size_i[0] == 1'b1 && address_i[1:0] == 2'b00)? 4'b1000 :
|
979 |
|
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b01)? 4'b0100 :
|
980 |
|
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b10)? 4'b0010 :
|
981 |
|
|
(size_i[0] == 1'b1 && address_i[1:0] == 2'b11)? 4'b0001 :
|
982 |
|
|
(size_i[1] == 1'b1 && address_i[1] == 2'b0)? 4'b1100 :
|
983 |
|
|
(size_i[0] == 1'b0 && address_i[1] == 2'b1)? 4'b0011 :
|
984 |
|
|
4'b1111;
|
985 |
12 |
alfik |
STB_O <= 1'b1;
|
986 |
|
|
|
987 |
|
|
if(read_modify_write_i == 1'b1) begin
|
988 |
|
|
SGL_O <= 1'b0;
|
989 |
|
|
BLK_O <= 1'b0;
|
990 |
|
|
RMW_O <= 1'b1;
|
991 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
992 |
|
|
end
|
993 |
13 |
alfik |
else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
994 |
12 |
alfik |
SGL_O <= 1'b0;
|
995 |
|
|
BLK_O <= 1'b1;
|
996 |
|
|
RMW_O <= 1'b0;
|
997 |
|
|
CTI_O <= CTI_INCR_CYCLE;
|
998 |
|
|
end
|
999 |
|
|
else begin
|
1000 |
|
|
SGL_O <= 1'b1;
|
1001 |
|
|
BLK_O <= 1'b0;
|
1002 |
|
|
RMW_O <= 1'b0;
|
1003 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1004 |
|
|
end
|
1005 |
|
|
|
1006 |
|
|
current_state <= S_READ_1;
|
1007 |
|
|
end
|
1008 |
|
|
end
|
1009 |
|
|
// write
|
1010 |
|
|
else if(do_write_i == 1'b1) begin
|
1011 |
|
|
WE_O <= 1'b1;
|
1012 |
|
|
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA;
|
1013 |
|
|
else fc_o <= FC_USER_DATA;
|
1014 |
|
|
|
1015 |
13 |
alfik |
if(address_i[0] == 1'b1 && size_i[0] == 1'b0) begin // WORD or LONG WORD
|
1016 |
12 |
alfik |
fault_address_state_o <= address_i;
|
1017 |
|
|
rw_state_o <= 1'b0;
|
1018 |
|
|
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_DATA : FC_USER_DATA;
|
1019 |
|
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
1020 |
|
|
|
1021 |
|
|
jmp_address_trap_o <= 1'b1;
|
1022 |
|
|
current_state <= S_WAIT;
|
1023 |
|
|
end
|
1024 |
|
|
else begin
|
1025 |
|
|
CYC_O <= 1'b1;
|
1026 |
|
|
ADR_O <= address_i[31:2];
|
1027 |
|
|
STB_O <= 1'b1;
|
1028 |
|
|
|
1029 |
13 |
alfik |
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
1030 |
12 |
alfik |
DAT_O <= { 16'b0, data_write_i[31:16] };
|
1031 |
|
|
SEL_O <= 4'b0011;
|
1032 |
|
|
end
|
1033 |
13 |
alfik |
else if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) begin
|
1034 |
12 |
alfik |
DAT_O <= data_write_i[31:0];
|
1035 |
|
|
SEL_O <= 4'b1111;
|
1036 |
|
|
end
|
1037 |
13 |
alfik |
else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) begin
|
1038 |
12 |
alfik |
DAT_O <= { 16'b0, data_write_i[15:0] };
|
1039 |
|
|
SEL_O <= 4'b0011;
|
1040 |
|
|
end
|
1041 |
13 |
alfik |
else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) begin
|
1042 |
12 |
alfik |
DAT_O <= { data_write_i[15:0], 16'b0 };
|
1043 |
|
|
SEL_O <= 4'b1100;
|
1044 |
|
|
end
|
1045 |
13 |
alfik |
else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) begin
|
1046 |
12 |
alfik |
DAT_O <= { 24'b0, data_write_i[7:0] };
|
1047 |
|
|
SEL_O <= 4'b0001;
|
1048 |
|
|
end
|
1049 |
13 |
alfik |
else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) begin
|
1050 |
12 |
alfik |
DAT_O <= { 16'b0, data_write_i[7:0], 8'b0 };
|
1051 |
|
|
SEL_O <= 4'b0010;
|
1052 |
|
|
end
|
1053 |
13 |
alfik |
else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) begin
|
1054 |
12 |
alfik |
DAT_O <= { 8'b0, data_write_i[7:0], 16'b0 };
|
1055 |
|
|
SEL_O <= 4'b0100;
|
1056 |
|
|
end
|
1057 |
13 |
alfik |
else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) begin
|
1058 |
12 |
alfik |
DAT_O <= { data_write_i[7:0], 24'b0 };
|
1059 |
|
|
SEL_O <= 4'b1000;
|
1060 |
|
|
end
|
1061 |
|
|
|
1062 |
|
|
if(read_modify_write_i == 1'b1) begin
|
1063 |
|
|
SGL_O <= 1'b0;
|
1064 |
|
|
BLK_O <= 1'b0;
|
1065 |
|
|
RMW_O <= 1'b1;
|
1066 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1067 |
|
|
end
|
1068 |
13 |
alfik |
else if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
1069 |
12 |
alfik |
SGL_O <= 1'b0;
|
1070 |
|
|
BLK_O <= 1'b1;
|
1071 |
|
|
RMW_O <= 1'b0;
|
1072 |
|
|
CTI_O <= CTI_INCR_CYCLE;
|
1073 |
|
|
end
|
1074 |
|
|
else begin
|
1075 |
|
|
SGL_O <= 1'b1;
|
1076 |
|
|
BLK_O <= 1'b0;
|
1077 |
|
|
RMW_O <= 1'b0;
|
1078 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1079 |
|
|
end
|
1080 |
|
|
|
1081 |
|
|
current_state <= S_WRITE_1;
|
1082 |
|
|
end
|
1083 |
|
|
end
|
1084 |
|
|
// pc
|
1085 |
|
|
else if(prefetch_ir_valid_o == 1'b0 || pc_change_i != 2'b00) begin
|
1086 |
|
|
|
1087 |
|
|
if(prefetch_ir_valid_o == 1'b0 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
|
1088 |
|
|
// load 4 words: [79:16] in 2,3 cycles
|
1089 |
|
|
prefetch_ir_valid_32_o <= 1'b0;
|
1090 |
|
|
prefetch_ir_valid_o <= 1'b0;
|
1091 |
|
|
prefetch_ir_valid_80_o <= 1'b0;
|
1092 |
|
|
|
1093 |
|
|
current_state <= S_PC_0;
|
1094 |
|
|
end
|
1095 |
|
|
else if(prefetch_ir_valid_80_o == 1'b0 && pc_change_i == 2'b01) begin
|
1096 |
|
|
// load 2 words: [31:0] in 1 cycle
|
1097 |
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
1098 |
|
|
prefetch_ir_valid_o <= 1'b0;
|
1099 |
|
|
prefetch_ir_valid_80_o <= 1'b0;
|
1100 |
|
|
|
1101 |
|
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
|
1102 |
|
|
current_state <= S_PC_0;
|
1103 |
|
|
end
|
1104 |
|
|
else begin
|
1105 |
|
|
// do not load any words
|
1106 |
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
1107 |
|
|
prefetch_ir_valid_o <= 1'b1;
|
1108 |
|
|
prefetch_ir_valid_80_o <= 1'b0;
|
1109 |
|
|
|
1110 |
|
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 };
|
1111 |
|
|
end
|
1112 |
|
|
|
1113 |
|
|
|
1114 |
|
|
end
|
1115 |
|
|
// interrupt
|
1116 |
|
|
else if(do_interrupt_i == 1'b1) begin
|
1117 |
|
|
CYC_O <= 1'b1;
|
1118 |
|
|
ADR_O <= { 27'b111_1111_1111_1111_1111_1111_1111, last_interrupt_mask };
|
1119 |
|
|
SEL_O <= 4'b1111;
|
1120 |
|
|
STB_O <= 1'b1;
|
1121 |
|
|
WE_O <= 1'b0;
|
1122 |
|
|
|
1123 |
|
|
SGL_O <= 1'b1;
|
1124 |
|
|
BLK_O <= 1'b0;
|
1125 |
|
|
RMW_O <= 1'b0;
|
1126 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1127 |
|
|
|
1128 |
|
|
fc_o <= FC_CPU_SPACE;
|
1129 |
|
|
|
1130 |
|
|
current_state <= S_INT_1;
|
1131 |
|
|
end
|
1132 |
|
|
end
|
1133 |
|
|
|
1134 |
|
|
S_RESET: begin
|
1135 |
|
|
reset_counter <= reset_counter - 8'd1;
|
1136 |
|
|
|
1137 |
|
|
if(reset_counter == 8'd0) begin
|
1138 |
|
|
finished_o <= 1'b1;
|
1139 |
|
|
current_state <= S_WAIT;
|
1140 |
|
|
end
|
1141 |
|
|
end
|
1142 |
|
|
|
1143 |
|
|
S_BLOCKED: begin
|
1144 |
|
|
end
|
1145 |
|
|
|
1146 |
|
|
S_INT_1: begin
|
1147 |
|
|
if(ACK_I == 1'b1) begin
|
1148 |
|
|
CYC_O <= 1'b0;
|
1149 |
|
|
STB_O <= 1'b0;
|
1150 |
|
|
|
1151 |
|
|
interrupt_trap_o <= DAT_I[7:0];
|
1152 |
|
|
|
1153 |
|
|
finished_o <= 1'b1;
|
1154 |
|
|
current_state <= S_WAIT;
|
1155 |
|
|
end
|
1156 |
|
|
else if(RTY_I == 1'b1) begin
|
1157 |
|
|
CYC_O <= 1'b0;
|
1158 |
|
|
STB_O <= 1'b0;
|
1159 |
|
|
|
1160 |
|
|
interrupt_trap_o <= 8'd24 + { 5'b0, interrupt_mask_o };
|
1161 |
|
|
|
1162 |
|
|
finished_o <= 1'b1;
|
1163 |
|
|
current_state <= S_WAIT;
|
1164 |
|
|
end
|
1165 |
|
|
else if(ERR_I == 1'b1) begin
|
1166 |
|
|
CYC_O <= 1'b0;
|
1167 |
|
|
STB_O <= 1'b0;
|
1168 |
|
|
|
1169 |
|
|
interrupt_trap_o <= 8'd24; // spurious interrupt
|
1170 |
|
|
|
1171 |
|
|
finished_o <= 1'b1;
|
1172 |
|
|
current_state <= S_WAIT;
|
1173 |
|
|
end
|
1174 |
|
|
end
|
1175 |
|
|
|
1176 |
|
|
S_PC_0: begin
|
1177 |
|
|
WE_O <= 1'b0;
|
1178 |
|
|
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
1179 |
|
|
else fc_o <= FC_USER_PROGRAM;
|
1180 |
|
|
|
1181 |
|
|
if(pc_i[0] == 1'b1) begin
|
1182 |
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
1183 |
|
|
prefetch_ir_valid_o <= 1'b1;
|
1184 |
|
|
prefetch_ir_valid_80_o <= 1'b1;
|
1185 |
|
|
|
1186 |
|
|
fault_address_state_o <= pc_i;
|
1187 |
|
|
rw_state_o <= 1'b1;
|
1188 |
|
|
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_PROGRAM : FC_USER_PROGRAM;
|
1189 |
|
|
interrupt_trap_o <= VECTOR_ADDRESS_TRAP;
|
1190 |
|
|
|
1191 |
|
|
jmp_address_trap_o <= 1'b1;
|
1192 |
|
|
current_state <= S_WAIT;
|
1193 |
|
|
end
|
1194 |
|
|
else begin
|
1195 |
|
|
CYC_O <= 1'b1;
|
1196 |
|
|
|
1197 |
|
|
if(prefetch_ir_valid_32_o == 1'b0) ADR_O <= pc_i[31:2];
|
1198 |
|
|
else ADR_O <= pc_i_plus_6[31:2];
|
1199 |
|
|
|
1200 |
|
|
SEL_O <= (pc_i[1:0] == 2'b10)? 4'b0011 :
|
1201 |
|
|
4'b1111;
|
1202 |
|
|
STB_O <= 1'b1;
|
1203 |
|
|
|
1204 |
|
|
if(prefetch_ir_valid_32_o == 1'b0) begin
|
1205 |
|
|
SGL_O <= 1'b0;
|
1206 |
|
|
BLK_O <= 1'b1;
|
1207 |
|
|
RMW_O <= 1'b0;
|
1208 |
|
|
CTI_O <= CTI_INCR_CYCLE;
|
1209 |
|
|
end
|
1210 |
|
|
else begin
|
1211 |
|
|
SGL_O <= 1'b1;
|
1212 |
|
|
BLK_O <= 1'b0;
|
1213 |
|
|
RMW_O <= 1'b0;
|
1214 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1215 |
|
|
end
|
1216 |
|
|
|
1217 |
|
|
saved_pc_change <= pc_change_i;
|
1218 |
|
|
prefetch_ir_valid_32_o <= 1'b0;
|
1219 |
|
|
|
1220 |
|
|
current_state <= S_PC_1;
|
1221 |
|
|
end
|
1222 |
|
|
end
|
1223 |
|
|
|
1224 |
|
|
S_PC_1: begin
|
1225 |
|
|
if(pc_change_i != 2'b00) saved_pc_change <= pc_change_i;
|
1226 |
|
|
|
1227 |
|
|
if(ACK_I == 1'b1) begin
|
1228 |
|
|
if(CTI_O == CTI_INCR_CYCLE) begin
|
1229 |
|
|
//CYC_O <= 1'b1;
|
1230 |
|
|
ADR_O <= pc_i_plus_4[31:2];
|
1231 |
|
|
SEL_O <= 4'b1111;
|
1232 |
|
|
//STB_O <= 1'b1;
|
1233 |
|
|
//WE_O <= 1'b0;
|
1234 |
|
|
|
1235 |
|
|
if(pc_i[1:0] == 2'b10) begin
|
1236 |
|
|
SGL_O <= 1'b0;
|
1237 |
|
|
BLK_O <= 1'b1;
|
1238 |
|
|
RMW_O <= 1'b0;
|
1239 |
|
|
CTI_O <= CTI_INCR_CYCLE;
|
1240 |
|
|
end
|
1241 |
|
|
else begin
|
1242 |
|
|
SGL_O <= 1'b0;
|
1243 |
|
|
BLK_O <= 1'b1;
|
1244 |
|
|
RMW_O <= 1'b0;
|
1245 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1246 |
|
|
end
|
1247 |
|
|
|
1248 |
|
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
1249 |
|
|
//else fc_o <= FC_USER_PROGRAM;
|
1250 |
|
|
|
1251 |
|
|
if(pc_i[1:0] == 2'b10) prefetch_ir_o <= { DAT_I[15:0], 64'b0 };
|
1252 |
|
|
else prefetch_ir_o <= { DAT_I[31:0], 48'b0 };
|
1253 |
|
|
|
1254 |
|
|
current_state <= S_PC_3;
|
1255 |
|
|
end
|
1256 |
|
|
else begin
|
1257 |
|
|
CYC_O <= 1'b0;
|
1258 |
|
|
STB_O <= 1'b0;
|
1259 |
|
|
|
1260 |
|
|
if(saved_pc_change == 2'b10 || saved_pc_change == 2'b11 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin
|
1261 |
|
|
// load 4 words: [79:16] in 2,3 cycles
|
1262 |
|
|
prefetch_ir_valid_32_o <= 1'b0;
|
1263 |
|
|
prefetch_ir_valid_o <= 1'b0;
|
1264 |
|
|
prefetch_ir_valid_80_o <= 1'b0;
|
1265 |
|
|
|
1266 |
|
|
current_state <= S_PC_0;
|
1267 |
|
|
end
|
1268 |
|
|
else if(saved_pc_change == 2'b01 || pc_change_i == 2'b01) begin
|
1269 |
|
|
// do not load any words
|
1270 |
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
1271 |
|
|
prefetch_ir_valid_o <= 1'b1;
|
1272 |
|
|
prefetch_ir_valid_80_o <= 1'b0;
|
1273 |
|
|
|
1274 |
|
|
prefetch_ir_o <= { prefetch_ir_o[63:32], DAT_I[31:0], 16'b0 };
|
1275 |
|
|
current_state <= S_INIT;
|
1276 |
|
|
end
|
1277 |
|
|
else begin
|
1278 |
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
1279 |
|
|
prefetch_ir_valid_o <= 1'b1;
|
1280 |
|
|
prefetch_ir_valid_80_o <= 1'b1;
|
1281 |
|
|
|
1282 |
|
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
|
1283 |
|
|
current_state <= S_INIT;
|
1284 |
|
|
end
|
1285 |
|
|
end
|
1286 |
|
|
end
|
1287 |
|
|
else if(RTY_I == 1'b1) begin
|
1288 |
|
|
CYC_O <= 1'b0;
|
1289 |
|
|
STB_O <= 1'b0;
|
1290 |
|
|
|
1291 |
|
|
current_state <= S_PC_2;
|
1292 |
|
|
end
|
1293 |
|
|
else if(ERR_I == 1'b1) begin
|
1294 |
|
|
CYC_O <= 1'b0;
|
1295 |
|
|
STB_O <= 1'b0;
|
1296 |
|
|
|
1297 |
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
1298 |
|
|
rw_state_o <= ~WE_O;
|
1299 |
|
|
fc_state_o <= fc_o;
|
1300 |
|
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
1301 |
|
|
|
1302 |
|
|
jmp_bus_trap_o <= 1'b1;
|
1303 |
|
|
current_state <= S_WAIT;
|
1304 |
|
|
end
|
1305 |
|
|
end
|
1306 |
|
|
S_PC_2: begin
|
1307 |
|
|
CYC_O <= 1'b1;
|
1308 |
|
|
STB_O <= 1'b1;
|
1309 |
|
|
|
1310 |
|
|
current_state <= S_PC_1;
|
1311 |
|
|
end
|
1312 |
|
|
S_PC_3: begin
|
1313 |
|
|
if(ACK_I == 1'b1) begin
|
1314 |
|
|
if(pc_i[1:0] == 2'b10) begin
|
1315 |
|
|
//CYC_O <= 1'b1;
|
1316 |
|
|
ADR_O <= pc_i_plus_6[31:2];
|
1317 |
|
|
SEL_O <= 4'b1111;
|
1318 |
|
|
//STB_O <= 1'b1;
|
1319 |
|
|
//WE_O <= 1'b0;
|
1320 |
|
|
|
1321 |
|
|
SGL_O <= 1'b0;
|
1322 |
|
|
BLK_O <= 1'b1;
|
1323 |
|
|
RMW_O <= 1'b0;
|
1324 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1325 |
|
|
|
1326 |
|
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM;
|
1327 |
|
|
//else fc_o <= FC_USER_PROGRAM;
|
1328 |
|
|
|
1329 |
|
|
prefetch_ir_o <= { prefetch_ir_o[79:64], DAT_I[31:0], 32'b0 };
|
1330 |
|
|
|
1331 |
|
|
current_state <= S_PC_5;
|
1332 |
|
|
end
|
1333 |
|
|
else begin
|
1334 |
|
|
CYC_O <= 1'b0;
|
1335 |
|
|
STB_O <= 1'b0;
|
1336 |
|
|
|
1337 |
|
|
prefetch_ir_o <= { prefetch_ir_o[79:48], DAT_I[31:0], 16'b0 };
|
1338 |
|
|
|
1339 |
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
1340 |
|
|
prefetch_ir_valid_o <= 1'b1;
|
1341 |
|
|
prefetch_ir_valid_80_o <= 1'b0;
|
1342 |
|
|
current_state <= S_INIT;
|
1343 |
|
|
end
|
1344 |
|
|
end
|
1345 |
|
|
else if(RTY_I == 1'b1) begin
|
1346 |
|
|
CYC_O <= 1'b0;
|
1347 |
|
|
STB_O <= 1'b0;
|
1348 |
|
|
|
1349 |
|
|
current_state <= S_PC_4;
|
1350 |
|
|
end
|
1351 |
|
|
else if(ERR_I == 1'b1) begin
|
1352 |
|
|
CYC_O <= 1'b0;
|
1353 |
|
|
STB_O <= 1'b0;
|
1354 |
|
|
|
1355 |
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
1356 |
|
|
rw_state_o <= ~WE_O;
|
1357 |
|
|
fc_state_o <= fc_o;
|
1358 |
|
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
1359 |
|
|
|
1360 |
|
|
jmp_bus_trap_o <= 1'b1;
|
1361 |
|
|
current_state <= S_WAIT;
|
1362 |
|
|
end
|
1363 |
|
|
end
|
1364 |
|
|
S_PC_4: begin
|
1365 |
|
|
CYC_O <= 1'b1;
|
1366 |
|
|
STB_O <= 1'b1;
|
1367 |
|
|
|
1368 |
|
|
current_state <= S_PC_3;
|
1369 |
|
|
end
|
1370 |
|
|
S_PC_5: begin
|
1371 |
|
|
if(ACK_I == 1'b1) begin
|
1372 |
|
|
CYC_O <= 1'b0;
|
1373 |
|
|
STB_O <= 1'b0;
|
1374 |
|
|
|
1375 |
|
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] };
|
1376 |
|
|
|
1377 |
|
|
prefetch_ir_valid_32_o <= 1'b1;
|
1378 |
|
|
prefetch_ir_valid_o <= 1'b1;
|
1379 |
|
|
prefetch_ir_valid_80_o <= 1'b1;
|
1380 |
|
|
current_state <= S_INIT;
|
1381 |
|
|
end
|
1382 |
|
|
else if(RTY_I == 1'b1) begin
|
1383 |
|
|
CYC_O <= 1'b0;
|
1384 |
|
|
STB_O <= 1'b0;
|
1385 |
|
|
|
1386 |
|
|
current_state <= S_PC_6;
|
1387 |
|
|
end
|
1388 |
|
|
else if(ERR_I == 1'b1) begin
|
1389 |
|
|
CYC_O <= 1'b0;
|
1390 |
|
|
STB_O <= 1'b0;
|
1391 |
|
|
|
1392 |
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
1393 |
|
|
rw_state_o <= ~WE_O;
|
1394 |
|
|
fc_state_o <= fc_o;
|
1395 |
|
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
1396 |
|
|
|
1397 |
|
|
jmp_bus_trap_o <= 1'b1;
|
1398 |
|
|
current_state <= S_WAIT;
|
1399 |
|
|
end
|
1400 |
|
|
end
|
1401 |
|
|
S_PC_6: begin
|
1402 |
|
|
CYC_O <= 1'b1;
|
1403 |
|
|
STB_O <= 1'b1;
|
1404 |
|
|
|
1405 |
|
|
current_state <= S_PC_5;
|
1406 |
|
|
end
|
1407 |
|
|
|
1408 |
|
|
//*******************
|
1409 |
|
|
S_READ_1: begin
|
1410 |
|
|
if(ACK_I == 1'b1) begin
|
1411 |
13 |
alfik |
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
1412 |
12 |
alfik |
//CYC_O <= 1'b1;
|
1413 |
|
|
ADR_O <= address_i_plus_4[31:2];
|
1414 |
|
|
SEL_O <= 4'b1100;
|
1415 |
|
|
//STB_O <= 1'b1;
|
1416 |
|
|
//WE_O <= 1'b0;
|
1417 |
|
|
|
1418 |
|
|
//SGL_O <= 1'b0;
|
1419 |
|
|
//BLK_O <= 1'b1;
|
1420 |
|
|
//RMW_O <= 1'b0;
|
1421 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1422 |
|
|
|
1423 |
|
|
//if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM;
|
1424 |
|
|
//else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM;
|
1425 |
|
|
|
1426 |
|
|
data_read_o <= { DAT_I[15:0], 16'b0 };
|
1427 |
|
|
|
1428 |
|
|
current_state <= S_READ_2;
|
1429 |
|
|
end
|
1430 |
|
|
else begin
|
1431 |
|
|
if(read_modify_write_i == 1'b1) begin
|
1432 |
|
|
CYC_O <= 1'b1;
|
1433 |
|
|
STB_O <= 1'b0;
|
1434 |
|
|
end
|
1435 |
|
|
else begin
|
1436 |
|
|
CYC_O <= 1'b0;
|
1437 |
|
|
STB_O <= 1'b0;
|
1438 |
|
|
end
|
1439 |
|
|
|
1440 |
13 |
alfik |
if(address_i[1:0] == 2'b00 && size_i[2] == 1'b1) data_read_o <= DAT_I[31:0];
|
1441 |
|
|
else if(address_i[1:0] == 2'b10 && size_i[1] == 1'b1) data_read_o <= { {16{DAT_I[15]}}, DAT_I[15:0] };
|
1442 |
|
|
else if(address_i[1:0] == 2'b00 && size_i[1] == 1'b1) data_read_o <= { {16{DAT_I[31]}}, DAT_I[31:16] };
|
1443 |
|
|
else if(address_i[1:0] == 2'b11 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[7]}}, DAT_I[7:0] };
|
1444 |
|
|
else if(address_i[1:0] == 2'b10 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[15]}}, DAT_I[15:8] };
|
1445 |
|
|
else if(address_i[1:0] == 2'b01 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[23]}}, DAT_I[23:16] };
|
1446 |
|
|
else if(address_i[1:0] == 2'b00 && size_i[0] == 1'b1) data_read_o <= { {24{DAT_I[31]}}, DAT_I[31:24] };
|
1447 |
12 |
alfik |
|
1448 |
|
|
finished_o <= 1'b1;
|
1449 |
|
|
current_state <= S_WAIT;
|
1450 |
|
|
end
|
1451 |
|
|
end
|
1452 |
|
|
else if(RTY_I == 1'b1) begin
|
1453 |
|
|
CYC_O <= 1'b0;
|
1454 |
|
|
STB_O <= 1'b0;
|
1455 |
|
|
|
1456 |
|
|
current_state <= S_INIT;
|
1457 |
|
|
end
|
1458 |
|
|
else if(ERR_I == 1'b1) begin
|
1459 |
|
|
CYC_O <= 1'b0;
|
1460 |
|
|
STB_O <= 1'b0;
|
1461 |
|
|
|
1462 |
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
1463 |
|
|
rw_state_o <= ~WE_O;
|
1464 |
|
|
fc_state_o <= fc_o;
|
1465 |
|
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
1466 |
|
|
|
1467 |
|
|
jmp_bus_trap_o <= 1'b1;
|
1468 |
|
|
current_state <= S_WAIT;
|
1469 |
|
|
end
|
1470 |
|
|
end
|
1471 |
|
|
S_READ_2: begin
|
1472 |
|
|
if(ACK_I == 1'b1) begin
|
1473 |
|
|
CYC_O <= 1'b0;
|
1474 |
|
|
STB_O <= 1'b0;
|
1475 |
|
|
|
1476 |
|
|
data_read_o <= { data_read_o[31:16], DAT_I[31:16] };
|
1477 |
|
|
|
1478 |
|
|
finished_o <= 1'b1;
|
1479 |
|
|
current_state <= S_WAIT;
|
1480 |
|
|
|
1481 |
|
|
end
|
1482 |
|
|
else if(RTY_I == 1'b1) begin
|
1483 |
|
|
CYC_O <= 1'b0;
|
1484 |
|
|
STB_O <= 1'b0;
|
1485 |
|
|
|
1486 |
|
|
current_state <= S_READ_3;
|
1487 |
|
|
end
|
1488 |
|
|
else if(ERR_I == 1'b1) begin
|
1489 |
|
|
CYC_O <= 1'b0;
|
1490 |
|
|
STB_O <= 1'b0;
|
1491 |
|
|
|
1492 |
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
1493 |
|
|
rw_state_o <= ~WE_O;
|
1494 |
|
|
fc_state_o <= fc_o;
|
1495 |
|
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
1496 |
|
|
|
1497 |
|
|
jmp_bus_trap_o <= 1'b1;
|
1498 |
|
|
current_state <= S_WAIT;
|
1499 |
|
|
end
|
1500 |
|
|
|
1501 |
|
|
end
|
1502 |
|
|
S_READ_3: begin
|
1503 |
|
|
CYC_O <= 1'b1;
|
1504 |
|
|
STB_O <= 1'b1;
|
1505 |
|
|
|
1506 |
|
|
current_state <= S_READ_2;
|
1507 |
|
|
end
|
1508 |
|
|
|
1509 |
|
|
|
1510 |
|
|
S_WAIT: begin
|
1511 |
|
|
jmp_address_trap_o <= 1'b0;
|
1512 |
|
|
jmp_bus_trap_o <= 1'b0;
|
1513 |
|
|
|
1514 |
|
|
if(do_read_i == 1'b0 && do_write_i == 1'b0 && do_interrupt_i == 1'b0 && do_reset_i == 1'b0) begin
|
1515 |
|
|
finished_o <= 1'b0;
|
1516 |
|
|
current_state <= S_INIT;
|
1517 |
|
|
end
|
1518 |
|
|
end
|
1519 |
|
|
|
1520 |
|
|
//**********************
|
1521 |
|
|
S_WRITE_1: begin
|
1522 |
|
|
if(ACK_I == 1'b1) begin
|
1523 |
13 |
alfik |
if(address_i[1:0] == 2'b10 && size_i[2] == 1'b1) begin
|
1524 |
12 |
alfik |
//CYC_O <= 1'b1;
|
1525 |
|
|
ADR_O <= address_i_plus_4[31:2];
|
1526 |
|
|
//STB_O <= 1'b1;
|
1527 |
|
|
//WE_O <= 1'b1;
|
1528 |
|
|
|
1529 |
|
|
DAT_O <= { data_write_i[15:0], 16'b0 };
|
1530 |
|
|
SEL_O <= 4'b1100;
|
1531 |
|
|
|
1532 |
|
|
//SGL_O <= 1'b0;
|
1533 |
|
|
//BLK_O <= 1'b1;
|
1534 |
|
|
//RMW_O <= 1'b0;
|
1535 |
|
|
CTI_O <= CTI_END_OF_BURST;
|
1536 |
|
|
|
1537 |
|
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA;
|
1538 |
|
|
//else fc_o <= FC_USER_DATA;
|
1539 |
|
|
|
1540 |
|
|
current_state <= S_WRITE_2;
|
1541 |
|
|
end
|
1542 |
|
|
else begin
|
1543 |
|
|
CYC_O <= 1'b0;
|
1544 |
|
|
STB_O <= 1'b0;
|
1545 |
|
|
|
1546 |
|
|
finished_o <= 1'b1;
|
1547 |
|
|
current_state <= S_WAIT;
|
1548 |
|
|
end
|
1549 |
|
|
end
|
1550 |
|
|
else if(RTY_I == 1'b1) begin
|
1551 |
|
|
CYC_O <= 1'b0;
|
1552 |
|
|
STB_O <= 1'b0;
|
1553 |
|
|
|
1554 |
|
|
current_state <= S_INIT;
|
1555 |
|
|
end
|
1556 |
|
|
else if(ERR_I == 1'b1) begin
|
1557 |
|
|
CYC_O <= 1'b0;
|
1558 |
|
|
STB_O <= 1'b0;
|
1559 |
|
|
|
1560 |
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
1561 |
|
|
rw_state_o <= ~WE_O;
|
1562 |
|
|
fc_state_o <= fc_o;
|
1563 |
|
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
1564 |
|
|
|
1565 |
|
|
jmp_bus_trap_o <= 1'b1;
|
1566 |
|
|
current_state <= S_WAIT;
|
1567 |
|
|
end
|
1568 |
|
|
|
1569 |
|
|
end
|
1570 |
|
|
S_WRITE_2: begin
|
1571 |
|
|
if(ACK_I == 1'b1) begin
|
1572 |
|
|
CYC_O <= 1'b0;
|
1573 |
|
|
STB_O <= 1'b0;
|
1574 |
|
|
|
1575 |
|
|
finished_o <= 1'b1;
|
1576 |
|
|
current_state <= S_WAIT;
|
1577 |
|
|
|
1578 |
|
|
end
|
1579 |
|
|
else if(RTY_I == 1'b1) begin
|
1580 |
|
|
CYC_O <= 1'b0;
|
1581 |
|
|
STB_O <= 1'b0;
|
1582 |
|
|
|
1583 |
|
|
current_state <= S_WRITE_3;
|
1584 |
|
|
end
|
1585 |
|
|
else if(ERR_I == 1'b1) begin
|
1586 |
|
|
CYC_O <= 1'b0;
|
1587 |
|
|
STB_O <= 1'b0;
|
1588 |
|
|
|
1589 |
|
|
fault_address_state_o <= { ADR_O, 2'b00 };
|
1590 |
|
|
rw_state_o <= ~WE_O;
|
1591 |
|
|
fc_state_o <= fc_o;
|
1592 |
|
|
interrupt_trap_o <= VECTOR_BUS_TRAP;
|
1593 |
|
|
|
1594 |
|
|
jmp_bus_trap_o <= 1'b1;
|
1595 |
|
|
current_state <= S_WAIT;
|
1596 |
|
|
end
|
1597 |
|
|
|
1598 |
|
|
end
|
1599 |
|
|
S_WRITE_3: begin
|
1600 |
|
|
CYC_O <= 1'b1;
|
1601 |
|
|
STB_O <= 1'b1;
|
1602 |
|
|
|
1603 |
|
|
current_state <= S_WRITE_2;
|
1604 |
|
|
end
|
1605 |
|
|
|
1606 |
|
|
endcase
|
1607 |
|
|
end
|
1608 |
|
|
end
|
1609 |
|
|
|
1610 |
|
|
endmodule
|
1611 |
|
|
|
1612 |
|
|
/***********************************************************************************************************************
|
1613 |
|
|
* Registers
|
1614 |
|
|
**********************************************************************************************************************/
|
1615 |
|
|
|
1616 |
|
|
/*! \brief Microcode controlled registers.
|
1617 |
|
|
*
|
1618 |
|
|
* Most of the ao68000 IP core registers are located in this module. At every clock cycle the microcode controls what
|
1619 |
|
|
* to save into these registers. Some of the more important registers include:
|
1620 |
|
|
* - operand1, operand2 registers are inputs to the ALU,
|
1621 |
|
|
* - address, size, do_read_flag, do_write_flag, do_interrupt_flag registers tell the bus_control module what kind
|
1622 |
|
|
* of bus cycle to perform,
|
1623 |
|
|
* - pc register stores the current program counter,
|
1624 |
|
|
* - ir register stores the current instruction word,
|
1625 |
|
|
* - ea_mod, ea_type registers store the currently selected addressing mode.
|
1626 |
|
|
*/
|
1627 |
|
|
module registers(
|
1628 |
|
|
input clock,
|
1629 |
|
|
input reset_n,
|
1630 |
|
|
|
1631 |
|
|
input [31:0] data_read,
|
1632 |
|
|
input [79:0] prefetch_ir,
|
1633 |
|
|
input prefetch_ir_valid,
|
1634 |
|
|
input [31:0] result,
|
1635 |
|
|
input [15:0] sr,
|
1636 |
|
|
input rw_state,
|
1637 |
|
|
input [2:0] fc_state,
|
1638 |
|
|
input [31:0] fault_address_state,
|
1639 |
|
|
input [7:0] interrupt_trap,
|
1640 |
|
|
input [2:0] interrupt_mask,
|
1641 |
|
|
input [7:0] decoder_trap,
|
1642 |
|
|
|
1643 |
|
|
input [31:0] usp,
|
1644 |
|
|
input [31:0] Dn_output,
|
1645 |
|
|
input [31:0] An_output,
|
1646 |
|
|
|
1647 |
|
|
output [1:0] pc_change,
|
1648 |
|
|
|
1649 |
|
|
output reg [2:0] ea_reg,
|
1650 |
|
|
input [2:0] ea_reg_control,
|
1651 |
|
|
|
1652 |
|
|
output reg [2:0] ea_mod,
|
1653 |
|
|
input [3:0] ea_mod_control,
|
1654 |
|
|
|
1655 |
|
|
output reg [3:0] ea_type,
|
1656 |
|
|
input [3:0] ea_type_control,
|
1657 |
|
|
|
1658 |
|
|
// for DIVU/DIVS simulation, register must be not zero
|
1659 |
|
|
output reg [31:0] operand1 = 32'hFFFFFFFF,
|
1660 |
|
|
input [3:0] operand1_control,
|
1661 |
|
|
|
1662 |
|
|
output reg [31:0] operand2 = 32'hFFFFFFFF,
|
1663 |
|
|
input [2:0] operand2_control,
|
1664 |
|
|
|
1665 |
|
|
output reg [31:0] address,
|
1666 |
|
|
output reg address_type,
|
1667 |
|
|
input [3:0] address_control,
|
1668 |
|
|
|
1669 |
13 |
alfik |
output reg [2:0] size,
|
1670 |
12 |
alfik |
input [3:0] size_control,
|
1671 |
|
|
|
1672 |
|
|
output reg [5:0] movem_modreg,
|
1673 |
|
|
input [2:0] movem_modreg_control,
|
1674 |
|
|
|
1675 |
|
|
output reg [4:0] movem_loop,
|
1676 |
|
|
input [1:0] movem_loop_control,
|
1677 |
|
|
|
1678 |
|
|
output reg [15:0] movem_reg,
|
1679 |
|
|
input [1:0] movem_reg_control,
|
1680 |
|
|
|
1681 |
|
|
output reg [15:0] ir,
|
1682 |
|
|
input [1:0] ir_control,
|
1683 |
|
|
|
1684 |
|
|
output reg [31:0] pc,
|
1685 |
|
|
input [2:0] pc_control,
|
1686 |
|
|
|
1687 |
|
|
output reg [7:0] trap,
|
1688 |
|
|
input [3:0] trap_control,
|
1689 |
|
|
|
1690 |
|
|
output reg [31:0] offset,
|
1691 |
|
|
input [1:0] offset_control,
|
1692 |
|
|
|
1693 |
|
|
output reg [31:0] index,
|
1694 |
|
|
input [1:0] index_control,
|
1695 |
|
|
|
1696 |
|
|
|
1697 |
|
|
output reg stop_flag,
|
1698 |
|
|
input [1:0] stop_flag_control,
|
1699 |
|
|
|
1700 |
|
|
output reg trace_flag,
|
1701 |
|
|
input [1:0] trace_flag_control,
|
1702 |
|
|
|
1703 |
|
|
output reg group_0_flag,
|
1704 |
|
|
input [1:0] group_0_flag_control,
|
1705 |
|
|
|
1706 |
|
|
output reg instruction_flag,
|
1707 |
|
|
input [1:0] instruction_flag_control,
|
1708 |
|
|
|
1709 |
|
|
output reg read_modify_write_flag,
|
1710 |
|
|
input [1:0] read_modify_write_flag_control,
|
1711 |
|
|
|
1712 |
|
|
output reg do_reset_flag,
|
1713 |
|
|
input [1:0] do_reset_flag_control,
|
1714 |
|
|
|
1715 |
|
|
output reg do_interrupt_flag,
|
1716 |
|
|
input [1:0] do_interrupt_flag_control,
|
1717 |
|
|
|
1718 |
|
|
output reg do_read_flag,
|
1719 |
|
|
input [1:0] do_read_flag_control,
|
1720 |
|
|
|
1721 |
|
|
output reg do_write_flag,
|
1722 |
|
|
input [1:0] do_write_flag_control,
|
1723 |
|
|
|
1724 |
|
|
output reg do_blocked_flag,
|
1725 |
|
|
input [1:0] do_blocked_flag_control,
|
1726 |
|
|
|
1727 |
|
|
output reg [31:0] data_write,
|
1728 |
|
|
input [1:0] data_write_control,
|
1729 |
|
|
|
1730 |
|
|
|
1731 |
|
|
output [3:0] An_address,
|
1732 |
|
|
input [1:0] An_address_control,
|
1733 |
|
|
|
1734 |
|
|
output [31:0] An_input,
|
1735 |
|
|
input [1:0] An_input_control,
|
1736 |
|
|
|
1737 |
|
|
output [2:0] Dn_address,
|
1738 |
16 |
alfik |
input Dn_address_control,
|
1739 |
|
|
|
1740 |
|
|
input [17:0] decoder_alu,
|
1741 |
|
|
output reg [17:0] decoder_alu_reg
|
1742 |
12 |
alfik |
);
|
1743 |
|
|
|
1744 |
|
|
reg [31:0] pc_valid;
|
1745 |
|
|
|
1746 |
|
|
// pc_change connected
|
1747 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1748 |
|
|
if(reset_n == 1'b0) begin
|
1749 |
|
|
pc <= 32'd0;
|
1750 |
|
|
pc_valid <= 32'd0;
|
1751 |
|
|
end
|
1752 |
|
|
else begin
|
1753 |
|
|
if(pc_control == `PC_FROM_RESULT) pc = result;
|
1754 |
|
|
else if(pc_control == `PC_INCR_BY_2) pc = pc + 32'd2;
|
1755 |
|
|
else if(pc_control == `PC_INCR_BY_4) pc = pc + 32'd4;
|
1756 |
13 |
alfik |
else if(pc_control == `PC_INCR_BY_SIZE) pc = (size[2] == 1'b0) ? pc + 32'd2 : pc + 32'd4;
|
1757 |
12 |
alfik |
else if(pc_control == `PC_FROM_PREFETCH_IR) pc = prefetch_ir[47:16];
|
1758 |
|
|
else if(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
1759 |
|
|
pc = pc + 32'd2;
|
1760 |
|
|
if(pc[0] == 1'b0) pc_valid <= pc;
|
1761 |
|
|
end
|
1762 |
|
|
end
|
1763 |
|
|
|
1764 |
|
|
assign pc_change =
|
1765 |
|
|
( pc_control == `PC_FROM_RESULT || pc_control == `PC_FROM_PREFETCH_IR
|
1766 |
|
|
) ? 2'b11 :
|
1767 |
13 |
alfik |
( pc_control == `PC_INCR_BY_4 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b1)
|
1768 |
12 |
alfik |
) ? 2'b10 :
|
1769 |
13 |
alfik |
( pc_control == `PC_INCR_BY_2 || (pc_control == `PC_INCR_BY_SIZE && size[2] == 1'b0) ||
|
1770 |
12 |
alfik |
(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
1771 |
|
|
) ? 2'b01 :
|
1772 |
|
|
2'b00;
|
1773 |
|
|
|
1774 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1775 |
13 |
alfik |
if(reset_n == 1'b0) begin
|
1776 |
|
|
size <= 2'b00;
|
1777 |
|
|
end
|
1778 |
15 |
alfik |
else if(size_control != `SIZE_IDLE) begin
|
1779 |
13 |
alfik |
// BYTE
|
1780 |
|
|
size[0] <= (size_control == `SIZE_BYTE)
|
1781 |
|
|
| ((size_control == `SIZE_3) && (ir[7:6] == 2'b00))
|
1782 |
|
|
| ((size_control == `SIZE_4) && (ir[13:12] == 2'b01))
|
1783 |
|
|
| ((size_control == `SIZE_6) && (ir[5:3] != 3'b000));
|
1784 |
|
|
// WORD
|
1785 |
|
|
size[1] <= (size_control == `SIZE_WORD)
|
1786 |
|
|
| ((size_control == `SIZE_1) && (ir[7:6] == 2'b00))
|
1787 |
|
|
| ((size_control == `SIZE_1_PLUS) && (ir[7:6] == 2'b10))
|
1788 |
|
|
| ((size_control == `SIZE_2) && (ir[6] == 1'b0))
|
1789 |
|
|
| ((size_control == `SIZE_3) && (ir[7:6] == 2'b01))
|
1790 |
|
|
| ((size_control == `SIZE_4) && (ir[13:12] == 2'b11))
|
1791 |
|
|
| ((size_control == `SIZE_5) && (ir[8] == 1'b0));
|
1792 |
|
|
// LONG
|
1793 |
|
|
size[2] <= (size_control == `SIZE_LONG)
|
1794 |
|
|
| ((size_control == `SIZE_1) && (ir[7:6] != 2'b00))
|
1795 |
|
|
| ((size_control == `SIZE_1_PLUS) && (ir[7:6] != 2'b10))
|
1796 |
|
|
| ((size_control == `SIZE_2) && (ir[6] == 1'b1))
|
1797 |
|
|
| ((size_control == `SIZE_3) && (ir[7] == 1'b1))
|
1798 |
|
|
| ((size_control == `SIZE_4) && (ir[12] == 1'b0))
|
1799 |
|
|
| ((size_control == `SIZE_5) && (ir[8] == 1'b1))
|
1800 |
|
|
| ((size_control == `SIZE_6) && (ir[5:3] == 3'b000));
|
1801 |
|
|
end
|
1802 |
|
|
end
|
1803 |
12 |
alfik |
|
1804 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1805 |
|
|
if(reset_n == 1'b0) ea_reg <= 3'b000;
|
1806 |
|
|
else if(ea_reg_control == `EA_REG_IR_2_0) ea_reg <= ir[2:0];
|
1807 |
|
|
else if(ea_reg_control == `EA_REG_IR_11_9) ea_reg <= ir[11:9];
|
1808 |
|
|
else if(ea_reg_control == `EA_REG_MOVEM_REG_2_0) ea_reg <= movem_modreg[2:0];
|
1809 |
|
|
else if(ea_reg_control == `EA_REG_3b111) ea_reg <= 3'b111;
|
1810 |
|
|
else if(ea_reg_control == `EA_REG_3b100) ea_reg <= 3'b100;
|
1811 |
|
|
end
|
1812 |
|
|
|
1813 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1814 |
|
|
if(reset_n == 1'b0) ea_mod <= 3'b000;
|
1815 |
|
|
else if(ea_mod_control == `EA_MOD_IR_5_3) ea_mod <= ir[5:3];
|
1816 |
|
|
else if(ea_mod_control == `EA_MOD_MOVEM_MOD_5_3) ea_mod <= movem_modreg[5:3];
|
1817 |
|
|
else if(ea_mod_control == `EA_MOD_IR_8_6) ea_mod <= ir[8:6];
|
1818 |
|
|
else if(ea_mod_control == `EA_MOD_PREDEC) ea_mod <= 3'b100;
|
1819 |
|
|
else if(ea_mod_control == `EA_MOD_3b111) ea_mod <= 3'b111;
|
1820 |
|
|
else if(ea_mod_control == `EA_MOD_DN_PREDEC) ea_mod <= (ir[3] == 1'b0) ? /* Dn */ 3'b000 : /* -(An) */ 3'b100;
|
1821 |
|
|
else if(ea_mod_control == `EA_MOD_DN_AN_EXG) ea_mod <= (ir[7:3] == 5'b01000 || ir[7:3] == 5'b10001) ? /* Dn */ 3'b000 : /* An */ 3'b001;
|
1822 |
|
|
else if(ea_mod_control == `EA_MOD_POSTINC) ea_mod <= 3'b011;
|
1823 |
|
|
else if(ea_mod_control == `EA_MOD_AN) ea_mod <= 3'b001;
|
1824 |
|
|
else if(ea_mod_control == `EA_MOD_DN) ea_mod <= 3'b000;
|
1825 |
|
|
else if(ea_mod_control == `EA_MOD_INDIRECTOFFSET) ea_mod <= 3'b101;
|
1826 |
|
|
end
|
1827 |
|
|
|
1828 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1829 |
|
|
if(reset_n == 1'b0) ea_type <= `EA_TYPE_IDLE;
|
1830 |
|
|
else if(ea_type_control == `EA_TYPE_ALL) ea_type <= `EA_TYPE_ALL;
|
1831 |
|
|
else if(ea_type_control == `EA_TYPE_CONTROL_POSTINC) ea_type <= `EA_TYPE_CONTROL_POSTINC;
|
1832 |
|
|
else if(ea_type_control == `EA_TYPE_CONTROLALTER_PREDEC) ea_type <= `EA_TYPE_CONTROLALTER_PREDEC;
|
1833 |
|
|
else if(ea_type_control == `EA_TYPE_CONTROL) ea_type <= `EA_TYPE_CONTROL;
|
1834 |
|
|
else if(ea_type_control == `EA_TYPE_DATAALTER) ea_type <= `EA_TYPE_DATAALTER;
|
1835 |
|
|
else if(ea_type_control == `EA_TYPE_DN_AN) ea_type <= `EA_TYPE_DN_AN;
|
1836 |
|
|
else if(ea_type_control == `EA_TYPE_MEMORYALTER) ea_type <= `EA_TYPE_MEMORYALTER;
|
1837 |
|
|
else if(ea_type_control == `EA_TYPE_DATA) ea_type <= `EA_TYPE_DATA;
|
1838 |
|
|
end
|
1839 |
|
|
|
1840 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1841 |
|
|
if(reset_n == 1'b0) operand1 <= 32'hFFFFFFFF;
|
1842 |
|
|
else if(operand1_control == `OP1_FROM_OP2) operand1 <= operand2;
|
1843 |
|
|
else if(operand1_control == `OP1_FROM_ADDRESS) operand1 <= address;
|
1844 |
|
|
else if(operand1_control == `OP1_FROM_DATA) operand1 <=
|
1845 |
13 |
alfik |
(size[0] == 1'b1) ? { {24{data_read[7]}}, data_read[7:0] } :
|
1846 |
|
|
(size[1] == 1'b1) ? { {16{data_read[15]}}, data_read[15:0] } :
|
1847 |
12 |
alfik |
data_read[31:0];
|
1848 |
|
|
else if(operand1_control == `OP1_FROM_IMMEDIATE) operand1 <=
|
1849 |
13 |
alfik |
(size[0] == 1'b1) ? { {24{prefetch_ir[71]}}, prefetch_ir[71:64] } :
|
1850 |
|
|
(size[1] == 1'b1) ? { {16{prefetch_ir[79]}}, prefetch_ir[79:64] } :
|
1851 |
12 |
alfik |
prefetch_ir[79:48];
|
1852 |
|
|
else if(operand1_control == `OP1_FROM_RESULT) operand1 <= result;
|
1853 |
|
|
else if(operand1_control == `OP1_MOVEQ) operand1 <= { {24{ir[7]}}, ir[7:0] };
|
1854 |
|
|
else if(operand1_control == `OP1_FROM_PC) operand1 <= pc_valid;
|
1855 |
|
|
else if(operand1_control == `OP1_LOAD_ZEROS) operand1 <= 32'b0;
|
1856 |
|
|
else if(operand1_control == `OP1_LOAD_ONES) operand1 <= 32'hFFFFFFFF;
|
1857 |
|
|
else if(operand1_control == `OP1_FROM_SR) operand1 <= { 16'b0, sr[15], 1'b0, sr[13], 2'b0, sr[10:8], 3'b0, sr[4:0] };
|
1858 |
|
|
else if(operand1_control == `OP1_FROM_USP) operand1 <= usp;
|
1859 |
|
|
else if(operand1_control == `OP1_FROM_AN) operand1 <=
|
1860 |
13 |
alfik |
(size[1] == 1'b1) ? { {16{An_output[15]}}, An_output[15:0] } :
|
1861 |
12 |
alfik |
An_output[31:0];
|
1862 |
|
|
else if(operand1_control == `OP1_FROM_DN) operand1 <=
|
1863 |
13 |
alfik |
(size[0] == 1'b1) ? { {24{Dn_output[7]}}, Dn_output[7:0] } :
|
1864 |
|
|
(size[1] == 1'b1) ? { {16{Dn_output[15]}}, Dn_output[15:0] } :
|
1865 |
12 |
alfik |
Dn_output[31:0];
|
1866 |
|
|
else if(operand1_control == `OP1_FROM_IR) operand1 <= { 16'b0, ir[15:0] };
|
1867 |
|
|
else if(operand1_control == `OP1_FROM_FAULT_ADDRESS) operand1 <= fault_address_state;
|
1868 |
|
|
end
|
1869 |
|
|
|
1870 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1871 |
|
|
if(reset_n == 1'b0) operand2 <= 32'hFFFFFFFF;
|
1872 |
|
|
else if(operand2_control == `OP2_FROM_OP1) operand2 <= operand1;
|
1873 |
|
|
else if(operand2_control == `OP2_LOAD_1) operand2 <= 32'd1;
|
1874 |
|
|
else if(operand2_control == `OP2_LOAD_COUNT) operand2 <=
|
1875 |
|
|
(ir[5] == 1'b0) ? ( (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] } ) :
|
1876 |
|
|
{ 26'b0, operand2[5:0] };
|
1877 |
|
|
else if(operand2_control == `OP2_ADDQ_SUBQ) operand2 <= (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] };
|
1878 |
|
|
else if(operand2_control == `OP2_MOVE_OFFSET) operand2 <= (ir[7:0] == 8'b0) ? operand2[31:0] : { {24{ir[7]}}, ir[7:0] };
|
1879 |
|
|
else if(operand2_control == `OP2_MOVE_ADDRESS_BUS_INFO) operand2 <= { 16'b0, 11'b0, rw_state, instruction_flag, fc_state};
|
1880 |
|
|
else if(operand2_control == `OP2_DECR_BY_1) operand2 <= operand2 - 32'b1;
|
1881 |
|
|
end
|
1882 |
|
|
|
1883 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1884 |
|
|
if(reset_n == 1'b0) address <= 32'b0;
|
1885 |
13 |
alfik |
else if(address_control == `ADDRESS_INCR_BY_SIZE) address <= ((size[0]) && ea_reg == 3'b111) ? address + 32'd2 : address + {29'd0,size};
|
1886 |
|
|
else if(address_control == `ADDRESS_DECR_BY_SIZE) address <= ((size[0]) && ea_reg == 3'b111) ? address - 32'd2 : address - {29'd0,size};
|
1887 |
|
|
else if(address_control == `ADDRESS_INCR_BY_2) address <= address + 32'd2;
|
1888 |
|
|
else if(address_control == `ADDRESS_FROM_AN_OUTPUT) address <= An_output;
|
1889 |
|
|
else if(address_control == `ADDRESS_FROM_BASE_INDEX_OFFSET) address <= address + index + offset;
|
1890 |
|
|
else if(address_control == `ADDRESS_FROM_IMM_16) address <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
|
1891 |
|
|
else if(address_control == `ADDRESS_FROM_IMM_32) address <= prefetch_ir[79:48];
|
1892 |
|
|
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address <= pc_valid + index + offset;
|
1893 |
|
|
else if(address_control == `ADDRESS_FROM_TRAP) address <= {22'b0, trap[7:0], 2'b0};
|
1894 |
|
|
end
|
1895 |
12 |
alfik |
|
1896 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1897 |
|
|
if(reset_n == 1'b0) address_type <= 1'b0;
|
1898 |
|
|
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address_type <= 1'b1;
|
1899 |
|
|
else if(address_control != `ADDRESS_IDLE) address_type <= 1'b0;
|
1900 |
|
|
end
|
1901 |
|
|
|
1902 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1903 |
|
|
if(reset_n == 1'b0) movem_modreg <= 6'b0;
|
1904 |
|
|
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_0) movem_modreg <= 6'b0;
|
1905 |
|
|
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_6b001111)movem_modreg <= 6'b001111;
|
1906 |
|
|
else if(movem_modreg_control == `MOVEM_MODREG_INCR_BY_1) movem_modreg <= movem_modreg + 6'd1;
|
1907 |
|
|
else if(movem_modreg_control == `MOVEM_MODREG_DECR_BY_1) movem_modreg <= movem_modreg - 6'd1;
|
1908 |
|
|
end
|
1909 |
|
|
|
1910 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1911 |
|
|
if(reset_n == 1'b0) movem_loop <= 5'b0;
|
1912 |
|
|
else if(movem_loop_control == `MOVEM_LOOP_LOAD_0) movem_loop <= 5'b0;
|
1913 |
|
|
else if(movem_loop_control == `MOVEM_LOOP_INCR_BY_1) movem_loop <= movem_loop + 5'd1;
|
1914 |
|
|
end
|
1915 |
|
|
|
1916 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1917 |
|
|
if(reset_n == 1'b0) movem_reg <= 16'b0;
|
1918 |
|
|
else if(movem_reg_control == `MOVEM_REG_FROM_OP1) movem_reg <= operand1[15:0];
|
1919 |
|
|
else if(movem_reg_control == `MOVEM_REG_SHIFT_RIGHT) movem_reg <= { 1'b0, movem_reg[15:1] };
|
1920 |
|
|
end
|
1921 |
|
|
|
1922 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1923 |
|
|
if(reset_n == 1'b0) ir <= 16'b0;
|
1924 |
|
|
else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
1925 |
|
|
ir <= prefetch_ir[79:64];
|
1926 |
|
|
end
|
1927 |
|
|
|
1928 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1929 |
16 |
alfik |
if(reset_n == 1'b0) decoder_alu_reg <= 18'b0;
|
1930 |
|
|
else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
1931 |
|
|
decoder_alu_reg <= decoder_alu;
|
1932 |
|
|
end
|
1933 |
|
|
|
1934 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1935 |
12 |
alfik |
if(reset_n == 1'b0) trap <= 8'd0;
|
1936 |
|
|
else if(trap_control == `TRAP_ILLEGAL_INSTR) trap <= 8'd4;
|
1937 |
|
|
else if(trap_control == `TRAP_DIV_BY_ZERO) trap <= 8'd5;
|
1938 |
|
|
else if(trap_control == `TRAP_CHK) trap <= 8'd6;
|
1939 |
|
|
else if(trap_control == `TRAP_TRAPV) trap <= 8'd7;
|
1940 |
|
|
else if(trap_control == `TRAP_PRIVIL_VIOLAT) trap <= 8'd8;
|
1941 |
|
|
else if(trap_control == `TRAP_TRACE) trap <= 8'd9;
|
1942 |
|
|
else if(trap_control == `TRAP_TRAP) trap <= { 4'b0010, ir[3:0] };
|
1943 |
|
|
else if(trap_control == `TRAP_FROM_DECODER) trap <= decoder_trap;
|
1944 |
|
|
else if(trap_control == `TRAP_FROM_INTERRUPT) trap <= interrupt_trap;
|
1945 |
|
|
end
|
1946 |
|
|
|
1947 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1948 |
|
|
if(reset_n == 1'b0) offset <= 32'd0;
|
1949 |
|
|
else if(offset_control == `OFFSET_IMM_8) offset <= { {24{prefetch_ir[71]}}, prefetch_ir[71:64] };
|
1950 |
|
|
else if(offset_control == `OFFSET_IMM_16) offset <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] };
|
1951 |
|
|
end
|
1952 |
|
|
|
1953 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1954 |
|
|
if(reset_n == 1'b0) index <= 32'd0;
|
1955 |
|
|
else if(index_control == `INDEX_0) index <= 32'd0;
|
1956 |
|
|
else if(index_control == `INDEX_LOAD_EXTENDED) index <=
|
1957 |
|
|
(prefetch_ir[79] == 1'b0) ?
|
1958 |
|
|
( (prefetch_ir[75] == 1'b0) ?
|
1959 |
|
|
{ {16{Dn_output[15]}}, Dn_output[15:0] } : Dn_output[31:0]
|
1960 |
|
|
) :
|
1961 |
|
|
( (prefetch_ir[75] == 1'b0) ?
|
1962 |
|
|
{ {16{An_output[15]}}, An_output[15:0] } : An_output[31:0]
|
1963 |
|
|
);
|
1964 |
|
|
end
|
1965 |
|
|
|
1966 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1967 |
|
|
if(reset_n == 1'b0) stop_flag <= 1'b0;
|
1968 |
|
|
else if(stop_flag_control == `STOP_FLAG_SET) stop_flag <= 1'b1;
|
1969 |
|
|
else if(stop_flag_control == `STOP_FLAG_CLEAR) stop_flag <= 1'b0;
|
1970 |
|
|
end
|
1971 |
|
|
|
1972 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1973 |
|
|
if(reset_n == 1'b0) trace_flag <= 1'b0;
|
1974 |
|
|
else if(trace_flag_control == `TRACE_FLAG_COPY_WHEN_NO_STOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
1975 |
|
|
trace_flag <= sr[15];
|
1976 |
|
|
end
|
1977 |
|
|
|
1978 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1979 |
|
|
if(reset_n == 1'b0) group_0_flag <= 1'b0;
|
1980 |
|
|
else if(group_0_flag_control == `GROUP_0_FLAG_SET) group_0_flag <= 1'b1;
|
1981 |
|
|
else if(group_0_flag_control == `GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0)
|
1982 |
|
|
group_0_flag <= 1'b0;
|
1983 |
|
|
end
|
1984 |
|
|
|
1985 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1986 |
|
|
if(reset_n == 1'b0) instruction_flag <= 1'b0;
|
1987 |
|
|
else if(instruction_flag_control == `INSTRUCTION_FLAG_SET) instruction_flag <= 1'b1;
|
1988 |
|
|
else if(instruction_flag_control == `INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0)
|
1989 |
|
|
instruction_flag <= 1'b0;
|
1990 |
|
|
end
|
1991 |
|
|
|
1992 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1993 |
|
|
if(reset_n == 1'b0) read_modify_write_flag <= 1'b0;
|
1994 |
|
|
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_SET) read_modify_write_flag <= 1'b1;
|
1995 |
|
|
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_CLEAR) read_modify_write_flag <= 1'b0;
|
1996 |
|
|
end
|
1997 |
|
|
|
1998 |
|
|
always @(posedge clock or negedge reset_n) begin
|
1999 |
|
|
if(reset_n == 1'b0) do_reset_flag <= 1'b0;
|
2000 |
|
|
else if(do_reset_flag_control == `DO_RESET_FLAG_SET) do_reset_flag <= 1'b1;
|
2001 |
|
|
else if(do_reset_flag_control == `DO_RESET_FLAG_CLEAR) do_reset_flag <= 1'b0;
|
2002 |
|
|
end
|
2003 |
|
|
|
2004 |
|
|
always @(posedge clock or negedge reset_n) begin
|
2005 |
|
|
if(reset_n == 1'b0) do_interrupt_flag <= 1'b0;
|
2006 |
|
|
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_SET_IF_ACTIVE) do_interrupt_flag <= (interrupt_mask != 3'b000) ? 1'b1 : 1'b0;
|
2007 |
|
|
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_CLEAR) do_interrupt_flag <= 1'b0;
|
2008 |
|
|
end
|
2009 |
|
|
|
2010 |
|
|
always @(posedge clock or negedge reset_n) begin
|
2011 |
|
|
if(reset_n == 1'b0) do_read_flag <= 1'b0;
|
2012 |
|
|
else if(do_read_flag_control == `DO_READ_FLAG_SET) do_read_flag <= 1'b1;
|
2013 |
|
|
else if(do_read_flag_control == `DO_READ_FLAG_CLEAR) do_read_flag <= 1'b0;
|
2014 |
|
|
end
|
2015 |
|
|
|
2016 |
|
|
always @(posedge clock or negedge reset_n) begin
|
2017 |
|
|
if(reset_n == 1'b0) do_write_flag <= 1'b0;
|
2018 |
|
|
else if(do_write_flag_control == `DO_WRITE_FLAG_SET) do_write_flag <= 1'b1;
|
2019 |
|
|
else if(do_write_flag_control == `DO_WRITE_FLAG_CLEAR) do_write_flag <= 1'b0;
|
2020 |
|
|
end
|
2021 |
|
|
|
2022 |
|
|
always @(posedge clock or negedge reset_n) begin
|
2023 |
|
|
if(reset_n == 1'b0) do_blocked_flag <= 1'b0;
|
2024 |
|
|
else if(do_blocked_flag_control == `DO_BLOCKED_FLAG_SET) do_blocked_flag <= 1'b1;
|
2025 |
|
|
end
|
2026 |
|
|
|
2027 |
|
|
always @(posedge clock or negedge reset_n) begin
|
2028 |
|
|
if(reset_n == 1'b0) data_write <= 32'd0;
|
2029 |
|
|
else if(data_write_control == `DATA_WRITE_FROM_RESULT) data_write <= result;
|
2030 |
|
|
end
|
2031 |
|
|
|
2032 |
|
|
assign An_address =
|
2033 |
|
|
(An_address_control == `AN_ADDRESS_FROM_EXTENDED) ? { sr[13], prefetch_ir[78:76] } :
|
2034 |
|
|
(An_address_control == `AN_ADDRESS_USP) ? 4'b0111 :
|
2035 |
|
|
(An_address_control == `AN_ADDRESS_SSP) ? 4'b1111 :
|
2036 |
|
|
{ sr[13], ea_reg };
|
2037 |
|
|
|
2038 |
|
|
assign An_input =
|
2039 |
|
|
(An_input_control == `AN_INPUT_FROM_ADDRESS) ? address :
|
2040 |
|
|
(An_input_control == `AN_INPUT_FROM_PREFETCH_IR) ? prefetch_ir[79:48] :
|
2041 |
|
|
result;
|
2042 |
|
|
|
2043 |
|
|
assign Dn_address = (Dn_address_control == `DN_ADDRESS_FROM_EXTENDED) ? prefetch_ir[78:76] : ea_reg;
|
2044 |
|
|
|
2045 |
|
|
endmodule
|
2046 |
|
|
|
2047 |
|
|
/***********************************************************************************************************************
|
2048 |
|
|
* Memory registers
|
2049 |
|
|
**********************************************************************************************************************/
|
2050 |
|
|
|
2051 |
|
|
/*! \brief Contains the microcode ROM and D0-D7, A0-A7 registers.
|
2052 |
|
|
*
|
2053 |
|
|
* The memory_registers module contains:
|
2054 |
|
|
* - data and address registers (D0-D7, A0-A7) implemented as an on-chip RAM.
|
2055 |
|
|
* - the microcode implemented as an on-chip ROM.
|
2056 |
|
|
*
|
2057 |
|
|
* Currently this module contains <em>altsyncram</em> instantiations
|
2058 |
|
|
* from Altera Megafunction/LPM library.
|
2059 |
|
|
*/
|
2060 |
|
|
module memory_registers(
|
2061 |
|
|
input clock,
|
2062 |
|
|
input reset_n,
|
2063 |
|
|
|
2064 |
|
|
// 0000,0001,0010,0011,0100,0101,0110: A0-A6, 0111: USP, 1111: SSP
|
2065 |
|
|
input [3:0] An_address,
|
2066 |
|
|
input [31:0] An_input,
|
2067 |
|
|
input An_write_enable,
|
2068 |
|
|
output [31:0] An_output,
|
2069 |
|
|
|
2070 |
|
|
output reg [31:0] usp,
|
2071 |
|
|
|
2072 |
|
|
input [2:0] Dn_address,
|
2073 |
|
|
input [31:0] Dn_input,
|
2074 |
|
|
input Dn_write_enable,
|
2075 |
13 |
alfik |
// 001: byte, 010: word, 100: long
|
2076 |
|
|
input [2:0] Dn_size,
|
2077 |
12 |
alfik |
output [31:0] Dn_output,
|
2078 |
|
|
|
2079 |
|
|
input [8:0] micro_pc,
|
2080 |
|
|
output [87:0] micro_data
|
2081 |
|
|
);
|
2082 |
|
|
|
2083 |
|
|
wire An_ram_write_enable = (An_address == 4'b0111) ? 1'b0 : An_write_enable;
|
2084 |
|
|
|
2085 |
|
|
wire [31:0] An_ram_output;
|
2086 |
|
|
assign An_output = (An_address == 4'b0111) ? usp : An_ram_output;
|
2087 |
|
|
|
2088 |
13 |
alfik |
wire [3:0] dn_byteena = (Dn_size[0] == 1'b1) ? 4'b0001 :
|
2089 |
|
|
(Dn_size[1] == 1'b1) ? 4'b0011 :
|
2090 |
|
|
(Dn_size[2] == 1'b1) ? 4'b1111 :
|
2091 |
12 |
alfik |
4'b0000;
|
2092 |
|
|
|
2093 |
|
|
always @(posedge clock or negedge reset_n) begin
|
2094 |
|
|
if(reset_n == 1'b0) usp <= 32'd0;
|
2095 |
|
|
else if(An_address == 4'b0111 && An_write_enable) usp <= An_input;
|
2096 |
|
|
end
|
2097 |
|
|
|
2098 |
|
|
// Register set An implemented as RAM.
|
2099 |
|
|
altsyncram an_ram_inst(
|
2100 |
|
|
.clock0 (clock),
|
2101 |
|
|
|
2102 |
|
|
.address_a (An_address[2:0]),
|
2103 |
|
|
.byteena_a (4'b1111),
|
2104 |
|
|
.wren_a (An_ram_write_enable),
|
2105 |
|
|
.data_a (An_input),
|
2106 |
|
|
.q_a (An_ram_output)
|
2107 |
|
|
);
|
2108 |
|
|
defparam
|
2109 |
|
|
an_ram_inst.operation_mode = "SINGLE_PORT",
|
2110 |
|
|
an_ram_inst.width_a = 32,
|
2111 |
|
|
an_ram_inst.widthad_a = 3,
|
2112 |
|
|
an_ram_inst.width_byteena_a = 4;
|
2113 |
|
|
|
2114 |
|
|
// Register set Dn implemented as RAM.
|
2115 |
|
|
altsyncram dn_ram_inst(
|
2116 |
|
|
.clock0 (clock),
|
2117 |
|
|
|
2118 |
|
|
.address_a (Dn_address),
|
2119 |
|
|
.byteena_a (dn_byteena),
|
2120 |
|
|
.wren_a (Dn_write_enable),
|
2121 |
|
|
.data_a (Dn_input),
|
2122 |
|
|
.q_a (Dn_output)
|
2123 |
|
|
);
|
2124 |
|
|
defparam
|
2125 |
|
|
dn_ram_inst.operation_mode = "SINGLE_PORT",
|
2126 |
|
|
dn_ram_inst.width_a = 32,
|
2127 |
|
|
dn_ram_inst.widthad_a = 3,
|
2128 |
|
|
dn_ram_inst.width_byteena_a = 4;
|
2129 |
|
|
|
2130 |
|
|
// Microcode ROM
|
2131 |
|
|
altsyncram micro_rom_inst(
|
2132 |
|
|
.clock0 (clock),
|
2133 |
|
|
|
2134 |
|
|
.address_a (micro_pc),
|
2135 |
|
|
.q_a (micro_data)
|
2136 |
|
|
);
|
2137 |
|
|
defparam
|
2138 |
|
|
micro_rom_inst.operation_mode = "ROM",
|
2139 |
|
|
micro_rom_inst.width_a = 88,
|
2140 |
|
|
micro_rom_inst.widthad_a = 9,
|
2141 |
|
|
micro_rom_inst.init_file = "ao68000_microcode.mif";
|
2142 |
|
|
|
2143 |
|
|
endmodule
|
2144 |
|
|
|
2145 |
|
|
/***********************************************************************************************************************
|
2146 |
|
|
* Instruction decoder
|
2147 |
|
|
**********************************************************************************************************************/
|
2148 |
|
|
|
2149 |
|
|
/*! \brief Decode instruction and addressing mode.
|
2150 |
|
|
*
|
2151 |
|
|
* The decoder is an instruction and addressing mode decoder. For instructions it takes as input the ir register
|
2152 |
|
|
* from the registers module. The output of the decoder, in this case, is a microcode address of the first microcode
|
2153 |
|
|
* word that performs the instruction.
|
2154 |
|
|
*
|
2155 |
|
|
* In case of addressing mode decoding, the output is the address of the first microcode word that performs the operand
|
2156 |
|
|
* loading or saving. This address is obtained from the currently selected addressing mode saved in the ea_mod
|
2157 |
|
|
* and ea_type registers in the registers module.
|
2158 |
|
|
*/
|
2159 |
|
|
module decoder(
|
2160 |
16 |
alfik |
input clock,
|
2161 |
|
|
input reset_n,
|
2162 |
12 |
alfik |
|
2163 |
16 |
alfik |
input supervisor,
|
2164 |
|
|
input [15:0] ir,
|
2165 |
12 |
alfik |
|
2166 |
|
|
// zero: no trap
|
2167 |
16 |
alfik |
output [7:0] decoder_trap,
|
2168 |
|
|
output [8:0] decoder_micropc,
|
2169 |
|
|
output [17:0] decoder_alu,
|
2170 |
12 |
alfik |
|
2171 |
16 |
alfik |
output [8:0] save_ea,
|
2172 |
|
|
output [8:0] perform_ea_write,
|
2173 |
|
|
output [8:0] perform_ea_read,
|
2174 |
|
|
output [8:0] load_ea,
|
2175 |
12 |
alfik |
|
2176 |
16 |
alfik |
input [3:0] ea_type,
|
2177 |
|
|
input [2:0] ea_mod,
|
2178 |
|
|
input [2:0] ea_reg
|
2179 |
12 |
alfik |
);
|
2180 |
|
|
|
2181 |
|
|
parameter [7:0]
|
2182 |
|
|
NO_TRAP = 8'd0,
|
2183 |
|
|
ILLEGAL_INSTRUCTION_TRAP = 8'd4,
|
2184 |
|
|
PRIVILEGE_VIOLATION_TRAP = 8'd8,
|
2185 |
|
|
ILLEGAL_1010_INSTRUCTION_TRAP = 8'd10,
|
2186 |
|
|
ILLEGAL_1111_INSTRUCTION_TRAP = 8'd11;
|
2187 |
|
|
|
2188 |
|
|
parameter [8:0]
|
2189 |
|
|
UNUSED_MICROPC = 9'd0;
|
2190 |
|
|
|
2191 |
|
|
assign { decoder_trap, decoder_micropc } =
|
2192 |
|
|
(reset_n == 1'b0) ? { NO_TRAP, UNUSED_MICROPC } :
|
2193 |
|
|
|
2194 |
|
|
// Privilege violation and illegal instruction
|
2195 |
|
|
|
2196 |
|
|
// ANDI to SR,EORI to SR,ORI to SR,RESET,STOP,RTE,MOVE TO SR,MOVE USP TO USP,MOVE USP TO An privileged instructions
|
2197 |
|
|
( ( ir[15:0] == 16'b0000_0010_01_111_100 ||
|
2198 |
|
|
ir[15:0] == 16'b0000_1010_01_111_100 ||
|
2199 |
|
|
ir[15:0] == 16'b0000_0000_01_111_100 ||
|
2200 |
|
|
ir[15:0] == 16'b0100_1110_0111_0000 ||
|
2201 |
|
|
ir[15:0] == 16'b0100_1110_0111_0010 ||
|
2202 |
|
|
ir[15:0] == 16'b0100_1110_0111_0011 ||
|
2203 |
|
|
(ir[15:6] == 10'b0100_0110_11 && ir[5:3] != 3'b001 && ir[5:0] != 6'b111_101 && ir[5:0] != 6'b111_110 && ir[5:0] != 6'b111_111) ||
|
2204 |
|
|
ir[15:3] == 13'b0100_1110_0110_0 ||
|
2205 |
|
|
ir[15:3] == 13'b0100_1110_0110_1 ) && supervisor == 1'b0 ) ? { PRIVILEGE_VIOLATION_TRAP, UNUSED_MICROPC } :
|
2206 |
|
|
// ILLEGAL, illegal instruction
|
2207 |
|
|
( ir[15:0] == 16'b0100_1010_11_111100 ) ? { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
2208 |
|
|
// 1010 illegal instruction
|
2209 |
|
|
( ir[15:12] == 4'b1010 ) ? { ILLEGAL_1010_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
2210 |
|
|
// 1111 illegal instruction
|
2211 |
|
|
( ir[15:12] == 4'b1111 ) ? { ILLEGAL_1111_INSTRUCTION_TRAP, UNUSED_MICROPC } :
|
2212 |
|
|
|
2213 |
|
|
// instruction decoding
|
2214 |
|
|
|
2215 |
|
|
// ANDI,EORI,ORI,ADDI,SUBI
|
2216 |
|
|
( ir[15:12] == 4'b0000 && ir[11:9] != 3'b100 && ir[11:9] != 3'b110 && ir[11:9] != 3'b111 && ir[8] == 1'b0 &&
|
2217 |
|
|
(ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) && ir[5:3] != 3'b001 &&
|
2218 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) &&
|
2219 |
|
|
ir[15:0] != 16'b0000_000_0_00_111100 && ir[15:0] != 16'b0000_000_0_01_111100 &&
|
2220 |
|
|
ir[15:0] != 16'b0000_001_0_00_111100 && ir[15:0] != 16'b0000_001_0_01_111100 &&
|
2221 |
|
|
ir[15:0] != 16'b0000_101_0_00_111100 && ir[15:0] != 16'b0000_101_0_01_111100 ) ? { NO_TRAP, `MICROPC_ANDI_EORI_ORI_ADDI_SUBI } :
|
2222 |
|
|
// ORI to CCR,ORI to SR,ANDI to CCR,ANDI to SR,EORI to CCR,EORI to SR
|
2223 |
|
|
( ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_000_0_01_111100 ||
|
2224 |
|
|
ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_001_0_01_111100 ||
|
2225 |
|
|
ir[15:0] == 16'b0000_101_0_00_111100 || ir[15:0] == 16'b0000_101_0_01_111100 ) ?
|
2226 |
|
|
{ NO_TRAP, `MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR } :
|
2227 |
|
|
// BTST register
|
2228 |
|
|
( ir[15:12] == 4'b0000 && ir[8:6] == 3'b100 && ir[5:3] != 3'b001 &&
|
2229 |
|
|
(ir[5:3] != 3'b111 ||
|
2230 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2231 |
|
|
) ? { NO_TRAP, `MICROPC_BTST_register } :
|
2232 |
|
|
// MOVEP memory to register
|
2233 |
|
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b00 || ir[7:6] == 2'b01 ) ) ?
|
2234 |
|
|
{ NO_TRAP, `MICROPC_MOVEP_memory_to_register } :
|
2235 |
|
|
// MOVEP register to memory
|
2236 |
|
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b10 || ir[7:6] == 2'b11 ) ) ?
|
2237 |
|
|
{ NO_TRAP, `MICROPC_MOVEP_register_to_memory } :
|
2238 |
|
|
// BCHG,BCLR,BSET register
|
2239 |
|
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] != 3'b100 &&
|
2240 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2241 |
|
|
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_register } :
|
2242 |
|
|
// BTST immediate
|
2243 |
|
|
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] == 2'b00 && ir[5:3] != 3'b001 &&
|
2244 |
|
|
(ir[5:3] != 3'b111 ||
|
2245 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
2246 |
|
|
) ? { NO_TRAP, `MICROPC_BTST_immediate } :
|
2247 |
|
|
// BCHG,BCLR,BSET immediate
|
2248 |
|
|
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] != 2'b00 && ir[5:3] != 3'b001 &&
|
2249 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2250 |
|
|
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_immediate } :
|
2251 |
|
|
// CMPI
|
2252 |
|
|
( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] == 3'b110 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
2253 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2254 |
|
|
) ? { NO_TRAP, `MICROPC_CMPI } :
|
2255 |
|
|
// MOVE
|
2256 |
|
|
( ir[15:14] == 2'b00 && ir[13:12] != 2'b00 && ir[8:6] != 3'b001 &&
|
2257 |
|
|
(ir[8:6] != 3'b111 || (ir[11:6] == 6'b000_111 || ir[11:6] == 6'b001_111)) &&
|
2258 |
|
|
(ir[13:12] != 2'b01 || ir[5:3] != 3'b001) &&
|
2259 |
|
|
(ir[5:3] != 3'b111 ||
|
2260 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2261 |
|
|
) ? { NO_TRAP, `MICROPC_MOVE } :
|
2262 |
|
|
// MOVEA
|
2263 |
|
|
( ir[15:14] == 2'b00 && (ir[13:12] == 2'b11 || ir[13:12] == 2'b10) && ir[8:6] == 3'b001 &&
|
2264 |
|
|
(ir[5:3] != 3'b111 ||
|
2265 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2266 |
|
|
) ? { NO_TRAP, `MICROPC_MOVEA } :
|
2267 |
|
|
// NEGX,CLR,NEG,NOT,NBCD
|
2268 |
|
|
( ir[15:12] == 4'b0100 && ir[5:3] != 3'b001 && (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001) &&
|
2269 |
|
|
( (ir[11:8] == 4'b0000 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0010 && ir[7:6] != 2'b11) ||
|
2270 |
|
|
(ir[11:8] == 4'b0100 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0110 && ir[7:6] != 2'b11) ||
|
2271 |
|
|
(ir[11:6] == 6'b1000_00)
|
2272 |
|
|
)
|
2273 |
|
|
) ? { NO_TRAP, `MICROPC_NEGX_CLR_NEG_NOT_NBCD } :
|
2274 |
|
|
// MOVE FROM SR
|
2275 |
|
|
( ir[15:6] == 10'b0100_0000_11 && ir[5:3] != 3'b001 && (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)
|
2276 |
|
|
) ? { NO_TRAP, `MICROPC_MOVE_FROM_SR } :
|
2277 |
|
|
// CHK
|
2278 |
|
|
( ir[15:12] == 4'b0100 && ir[8:6] == 3'b110 && ir[5:3] != 3'b001 &&
|
2279 |
|
|
(ir[5:3] != 3'b111 ||
|
2280 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2281 |
|
|
) ? { NO_TRAP, `MICROPC_CHK } :
|
2282 |
|
|
// LEA
|
2283 |
|
|
( ir[15:12] == 4'b0100 && ir[8:6] == 3'b111 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
|
2284 |
|
|
(ir[5:3] != 3'b111 ||
|
2285 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
2286 |
|
|
) ? { NO_TRAP, `MICROPC_LEA } :
|
2287 |
|
|
// MOVE TO CCR, MOVE TO SR
|
2288 |
|
|
( (ir[15:6] == 10'b0100_0100_11 || ir[15:6] == 10'b0100_0110_11) && ir[5:3] != 3'b001 &&
|
2289 |
|
|
(ir[5:3] != 3'b111 ||
|
2290 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2291 |
|
|
) ? { NO_TRAP, `MICROPC_MOVE_TO_CCR_MOVE_TO_SR } :
|
2292 |
|
|
// SWAP,EXT
|
2293 |
|
|
( ir[15:12] == 4'b0100 && (ir[11:3] == 9'b1000_01_000 || (ir[11:7] == 5'b1000_1 && ir[5:3] == 3'b000) ) ) ? { NO_TRAP, `MICROPC_SWAP_EXT } :
|
2294 |
|
|
// PEA
|
2295 |
|
|
( ir[15:6] == 10'b0100_1000_01 && ir[5:3] != 3'b000 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
|
2296 |
|
|
(ir[5:3] != 3'b111 ||
|
2297 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
2298 |
|
|
) ? { NO_TRAP, `MICROPC_PEA } :
|
2299 |
|
|
// MOVEM register to memory, predecrement
|
2300 |
|
|
( ir[15:7] == 9'b0100_1000_1 && ir[5:3] == 3'b100 ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_predecrement } :
|
2301 |
|
|
// MOVEM register to memory, control
|
2302 |
|
|
( ir[15:7] == 9'b0100_1000_1 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
|
2303 |
|
|
(ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)
|
2304 |
|
|
) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_control } :
|
2305 |
|
|
// TST
|
2306 |
|
|
( ir[15:8] == 8'b0100_1010 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
2307 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2308 |
|
|
) ? { NO_TRAP, `MICROPC_TST } :
|
2309 |
|
|
// TAS
|
2310 |
|
|
( ir[15:6] == 10'b0100_1010_11 && ir[5:3] != 3'b001 &&
|
2311 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2312 |
|
|
) ? { NO_TRAP, `MICROPC_TAS } :
|
2313 |
|
|
// MOVEM memory to register
|
2314 |
|
|
( ir[15:7] == 9'b0100_1100_1 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b011 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
|
2315 |
|
|
(ir[5:3] != 3'b111 ||
|
2316 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
2317 |
|
|
) ? { NO_TRAP, `MICROPC_MOVEM_memory_to_register } :
|
2318 |
|
|
// TRAP
|
2319 |
|
|
( ir[15:4] == 12'b0100_1110_0100 ) ? { NO_TRAP, `MICROPC_TRAP } :
|
2320 |
|
|
// LINK
|
2321 |
|
|
( ir[15:3] == 13'b0100_1110_0101_0 ) ? { NO_TRAP, `MICROPC_LINK } :
|
2322 |
|
|
// UNLK
|
2323 |
|
|
( ir[15:3] == 13'b0100_1110_0101_1 ) ? { NO_TRAP, `MICROPC_ULNK } :
|
2324 |
|
|
// MOVE USP to USP
|
2325 |
|
|
( ir[15:3] == 13'b0100_1110_0110_0 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_USP } :
|
2326 |
|
|
// MOVE USP to An
|
2327 |
|
|
( ir[15:3] == 13'b0100_1110_0110_1 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_An } :
|
2328 |
|
|
// RESET
|
2329 |
|
|
( ir[15:0] == 16'b0100_1110_0111_0000 ) ? { NO_TRAP, `MICROPC_RESET } :
|
2330 |
|
|
// NOP
|
2331 |
|
|
( ir[15:0] == 16'b0100_1110_0111_0001 ) ? { NO_TRAP, `MICROPC_NOP } :
|
2332 |
|
|
// STOP
|
2333 |
|
|
( ir[15:0] == 16'b0100_1110_0111_0010 ) ? { NO_TRAP, `MICROPC_STOP } :
|
2334 |
|
|
// RTE,RTR
|
2335 |
|
|
( ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0111 ) ? { NO_TRAP, `MICROPC_RTE_RTR } :
|
2336 |
|
|
// RTS
|
2337 |
|
|
( ir[15:0] == 16'b0100_1110_0111_0101 ) ? { NO_TRAP, `MICROPC_RTS } :
|
2338 |
|
|
// TRAPV
|
2339 |
|
|
( ir[15:0] == 16'b0100_1110_0111_0110 ) ? { NO_TRAP, `MICROPC_TRAPV } :
|
2340 |
|
|
// JSR
|
2341 |
|
|
( ir[15:6] == 10'b0100_1110_10 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
|
2342 |
|
|
(ir[5:3] != 3'b111 ||
|
2343 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
2344 |
|
|
) ? { NO_TRAP, `MICROPC_JSR } :
|
2345 |
|
|
// JMP
|
2346 |
|
|
( ir[15:6] == 10'b0100_1110_11 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) &&
|
2347 |
|
|
(ir[5:3] != 3'b111 ||
|
2348 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011))
|
2349 |
|
|
) ? { NO_TRAP, `MICROPC_JMP } :
|
2350 |
|
|
// ADDQ,SUBQ not An
|
2351 |
|
|
( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 &&
|
2352 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2353 |
|
|
) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_not_An } :
|
2354 |
|
|
// ADDQ,SUBQ An
|
2355 |
|
|
( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[7:6] != 2'b00 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_An } :
|
2356 |
|
|
// Scc
|
2357 |
|
|
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
|
2358 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2359 |
|
|
) ? { NO_TRAP, `MICROPC_Scc } :
|
2360 |
|
|
// DBcc
|
2361 |
|
|
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_DBcc } :
|
2362 |
|
|
// BSR
|
2363 |
|
|
( ir[15:12] == 4'b0110 && ir[11:8] == 4'b0001 ) ? { NO_TRAP, `MICROPC_BSR } :
|
2364 |
|
|
// Bcc,BRA
|
2365 |
|
|
( ir[15:12] == 4'b0110 && ir[11:8] != 4'b0001 ) ? { NO_TRAP, `MICROPC_Bcc_BRA } :
|
2366 |
|
|
// MOVEQ
|
2367 |
|
|
( ir[15:12] == 4'b0111 && ir[8] == 1'b0 ) ? { NO_TRAP, `MICROPC_MOVEQ } :
|
2368 |
|
|
// CMP
|
2369 |
|
|
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
|
2370 |
|
|
(ir[8:6] != 3'b000 || ir[5:3] != 3'b001) &&
|
2371 |
|
|
(ir[5:3] != 3'b111 ||
|
2372 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2373 |
|
|
) ? { NO_TRAP, `MICROPC_CMP } :
|
2374 |
|
|
// CMPA
|
2375 |
|
|
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
|
2376 |
|
|
(ir[5:3] != 3'b111 ||
|
2377 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2378 |
|
|
) ? { NO_TRAP, `MICROPC_CMPA } :
|
2379 |
|
|
// CMPM
|
2380 |
|
|
( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001) ? { NO_TRAP, `MICROPC_CMPM } :
|
2381 |
|
|
// EOR
|
2382 |
|
|
( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001 &&
|
2383 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2384 |
|
|
) ? { NO_TRAP, `MICROPC_EOR } :
|
2385 |
|
|
// ADD to mem,SUB to mem,AND to mem,OR to mem
|
2386 |
|
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
|
2387 |
|
|
(ir[8:4] == 5'b10001 || ir[8:4] == 5'b10010 || ir[8:4] == 5'b10011 ||
|
2388 |
|
|
ir[8:4] == 5'b10101 || ir[8:4] == 5'b10110 || ir[8:4] == 5'b10111 ||
|
2389 |
|
|
ir[8:4] == 5'b11001 || ir[8:4] == 5'b11010 || ir[8:4] == 5'b11011) &&
|
2390 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2391 |
|
|
) ? { NO_TRAP, `MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem } :
|
2392 |
|
|
// ADD to Dn,SUB to Dn,AND to Dn,OR to Dn
|
2393 |
|
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) &&
|
2394 |
|
|
(ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) &&
|
2395 |
|
|
(ir[12] != 1'b1 || ir[8:6] != 3'b000 || ir[5:3] != 3'b001) && (ir[12] == 1'b1 || ir[5:3] != 3'b001) &&
|
2396 |
|
|
(ir[5:3] != 3'b111 ||
|
2397 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2398 |
|
|
) ? { NO_TRAP, `MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn } :
|
2399 |
|
|
// ADDA,SUBA
|
2400 |
|
|
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) &&
|
2401 |
|
|
(ir[5:3] != 3'b111 ||
|
2402 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2403 |
|
|
) ? { NO_TRAP, `MICROPC_ADDA_SUBA } :
|
2404 |
|
|
// ABCD,SBCD,ADDX,SUBX
|
2405 |
|
|
( ((ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[8:4] == 5'b10000) ||
|
2406 |
|
|
((ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:4] == 5'b10000 || ir[8:4] == 5'b10100 || ir[8:4] == 5'b11000) ) ) ?
|
2407 |
|
|
{ NO_TRAP, `MICROPC_ABCD_SBCD_ADDX_SUBX } :
|
2408 |
|
|
// EXG
|
2409 |
|
|
( ir[15:12] == 4'b1100 && (ir[8:3] == 6'b101000 || ir[8:3] == 6'b101001 || ir[8:3] == 6'b110001) ) ? { NO_TRAP, `MICROPC_EXG } :
|
2410 |
|
|
// MULS,MULU,DIVS,DIVU
|
2411 |
|
|
( (ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 &&
|
2412 |
|
|
(ir[5:3] != 3'b111 ||
|
2413 |
|
|
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100))
|
2414 |
|
|
) ? { NO_TRAP, `MICROPC_MULS_MULU_DIVS_DIVU } :
|
2415 |
|
|
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all memory
|
2416 |
|
|
( ir[15:12] == 4'b1110 && ir[11] == 1'b0 && ir[7:6] == 2'b11 && ir[5:3] != 3'b000 && ir[5:3] != 3'b001 &&
|
2417 |
|
|
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001))
|
2418 |
|
|
) ? { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory } :
|
2419 |
|
|
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all immediate/register
|
2420 |
|
|
( ir[15:12] == 4'b1110 && (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) ) ?
|
2421 |
|
|
{ NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register } :
|
2422 |
|
|
|
2423 |
|
|
// else
|
2424 |
|
|
|
2425 |
|
|
{ ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC }
|
2426 |
|
|
;
|
2427 |
|
|
|
2428 |
|
|
// load ea
|
2429 |
|
|
assign load_ea =
|
2430 |
|
|
(
|
2431 |
|
|
(ea_type == `EA_TYPE_ALL && (ea_mod == 3'b000 || ea_mod == 3'b001 || (ea_mod == 3'b111 && ea_reg == 3'b100))) ||
|
2432 |
|
|
(ea_type == `EA_TYPE_DATAALTER && ea_mod == 3'b000) ||
|
2433 |
|
|
(ea_type == `EA_TYPE_DN_AN && (ea_mod == 3'b000 || ea_mod == 3'b001)) ||
|
2434 |
|
|
(ea_type == `EA_TYPE_DATA && (ea_mod == 3'b000 || (ea_mod == 3'b111 && ea_reg == 3'b100)))
|
2435 |
|
|
) ? 9'd0 // no ea needed
|
2436 |
|
|
:
|
2437 |
|
|
(ea_mod == 3'b010 && (
|
2438 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
2439 |
|
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER ||
|
2440 |
|
|
ea_type == `EA_TYPE_DATA
|
2441 |
|
|
)) ? `MICROPC_LOAD_EA_An // (An)
|
2442 |
|
|
:
|
2443 |
|
|
(ea_mod == 3'b011 && (
|
2444 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
|
2445 |
|
|
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
|
2446 |
|
|
)) ? `MICROPC_LOAD_EA_An_plus // (An)+
|
2447 |
|
|
:
|
2448 |
|
|
(ea_mod == 3'b100 && (
|
2449 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
|
2450 |
|
|
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
2451 |
|
|
)) ? `MICROPC_LOAD_EA_minus_An // -(An)
|
2452 |
|
|
:
|
2453 |
|
|
(ea_mod == 3'b101 && (
|
2454 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
2455 |
|
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
2456 |
|
|
)) ? `MICROPC_LOAD_EA_d16_An // (d16, An)
|
2457 |
|
|
:
|
2458 |
|
|
(ea_mod == 3'b110 && (
|
2459 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
2460 |
|
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
2461 |
|
|
)) ? `MICROPC_LOAD_EA_d8_An_Xn // (d8, An, Xn)
|
2462 |
|
|
:
|
2463 |
|
|
(ea_mod == 3'b111 && ea_reg == 3'b000 && (
|
2464 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
2465 |
|
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
2466 |
|
|
)) ? `MICROPC_LOAD_EA_xxx_W // (xxx).W
|
2467 |
|
|
:
|
2468 |
|
|
(ea_mod == 3'b111 && ea_reg == 3'b001 && (
|
2469 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC ||
|
2470 |
|
|
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
2471 |
|
|
)) ? `MICROPC_LOAD_EA_xxx_L // (xxx).L
|
2472 |
|
|
:
|
2473 |
|
|
(ea_mod == 3'b111 && ea_reg == 3'b010 && (
|
2474 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
|
2475 |
|
|
)) ? `MICROPC_LOAD_EA_d16_PC // (d16, PC)
|
2476 |
|
|
:
|
2477 |
|
|
(ea_mod == 3'b111 && ea_reg == 3'b011 && (
|
2478 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA
|
2479 |
|
|
)) ? `MICROPC_LOAD_EA_d8_PC_Xn // (d8, PC, Xn)
|
2480 |
|
|
:
|
2481 |
|
|
`MICROPC_LOAD_EA_illegal_command // illegal command
|
2482 |
|
|
;
|
2483 |
|
|
|
2484 |
|
|
// perform ea read
|
2485 |
|
|
assign perform_ea_read =
|
2486 |
|
|
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
|
2487 |
|
|
ea_type == `EA_TYPE_DATA) ) ?
|
2488 |
|
|
`MICROPC_PERFORM_EA_READ_Dn :
|
2489 |
|
|
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_READ_An :
|
2490 |
|
|
( ea_mod == 3'b111 && ea_reg == 3'b100 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATA) ) ?
|
2491 |
|
|
`MICROPC_PERFORM_EA_READ_imm :
|
2492 |
|
|
`MICROPC_PERFORM_EA_READ_memory
|
2493 |
|
|
;
|
2494 |
|
|
|
2495 |
|
|
// perform ea write
|
2496 |
|
|
assign perform_ea_write =
|
2497 |
|
|
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN ||
|
2498 |
|
|
ea_type == `EA_TYPE_DATA) ) ?
|
2499 |
|
|
`MICROPC_PERFORM_EA_WRITE_Dn :
|
2500 |
|
|
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_WRITE_An :
|
2501 |
|
|
`MICROPC_PERFORM_EA_WRITE_memory
|
2502 |
|
|
;
|
2503 |
|
|
|
2504 |
|
|
// save ea
|
2505 |
|
|
assign save_ea =
|
2506 |
|
|
(ea_mod == 3'b011 && (
|
2507 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER ||
|
2508 |
|
|
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA
|
2509 |
|
|
)) ? `MICROPC_SAVE_EA_An_plus // (An)+
|
2510 |
|
|
:
|
2511 |
|
|
(ea_mod == 3'b100 && (
|
2512 |
|
|
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER ||
|
2513 |
|
|
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA
|
2514 |
|
|
)) ? `MICROPC_SAVE_EA_minus_An // -(An)
|
2515 |
|
|
:
|
2516 |
|
|
9'd0 // no ea needed
|
2517 |
|
|
;
|
2518 |
|
|
|
2519 |
16 |
alfik |
// ALU decoding optimization
|
2520 |
|
|
// Thanks to Frederic Requin
|
2521 |
|
|
// not used: 7, 13, 17
|
2522 |
|
|
assign decoder_alu[0] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b000) // OR
|
2523 |
|
|
|| (ir[15:12] == 4'b1000));
|
2524 |
|
|
assign decoder_alu[1] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b001) // AND
|
2525 |
|
|
|| (ir[15:12] == 4'b1100));
|
2526 |
|
|
assign decoder_alu[2] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b101) // EOR
|
2527 |
|
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001));
|
2528 |
|
|
assign decoder_alu[3] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) // ADD
|
2529 |
|
|
|| (ir[15:12] == 4'b1101)
|
2530 |
|
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
|
2531 |
|
|
assign decoder_alu[4] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) // SUB
|
2532 |
|
|
|| (ir[15:12] == 4'b1001)
|
2533 |
|
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
|
2534 |
|
|
assign decoder_alu[5] = ((ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) // CMP
|
2535 |
|
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b10 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001)
|
2536 |
|
|
|| (ir[15:12] == 4'b1011 && (ir[8:7] == 2'b00 || ir[8:6] == 3'b010)));
|
2537 |
|
|
assign decoder_alu[6] = ((ir[15:12] == 4'b1101) // ADDA,ADDQ
|
2538 |
|
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b0));
|
2539 |
|
|
assign decoder_alu[7] = ((ir[15:12] == 4'b1001) // SUBA,CMPA,SUBQ
|
2540 |
|
|
|| (ir[15:12] == 4'b1011)
|
2541 |
|
|
|| (ir[15:12] == 4'b0101 && ir[8] == 1'b1));
|
2542 |
|
|
assign decoder_alu[8] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) // ASL
|
2543 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b1);
|
2544 |
|
|
assign decoder_alu[9] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) // LSL
|
2545 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b1);
|
2546 |
|
|
assign decoder_alu[10] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) // ROL
|
2547 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b1);
|
2548 |
|
|
assign decoder_alu[11] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) // ROXL
|
2549 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b1);
|
2550 |
|
|
assign decoder_alu[12] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) // ASR
|
2551 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b0);
|
2552 |
|
|
assign decoder_alu[13] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) // LSR
|
2553 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b0);
|
2554 |
|
|
assign decoder_alu[14] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) // ROR
|
2555 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b0);
|
2556 |
|
|
assign decoder_alu[15] = (((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) // ROXR
|
2557 |
|
|
|| (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b0);
|
2558 |
|
|
assign decoder_alu[16] = ((ir[15:8] == 8'b0100_0110) // SR operations
|
2559 |
|
|
|| (ir[15:0] == 16'b0100_1110_0111_0011)
|
2560 |
|
|
|| (ir[15:0] == 16'b0100_1110_0111_0010)
|
2561 |
|
|
|| (ir[15:0] == 16'b0000_000_0_01_111100)
|
2562 |
|
|
|| (ir[15:0] == 16'b0000_001_0_01_111100)
|
2563 |
|
|
|| (ir[15:0] == 16'b0000_101_0_01_111100));
|
2564 |
|
|
assign decoder_alu[17] = ((ir[15:8] == 8'b0100_0100) // CCR operations
|
2565 |
|
|
|| (ir[15:0] == 16'b0100_1110_0111_0111)
|
2566 |
|
|
|| (ir[15:0] == 16'b0000_000_0_00_111100)
|
2567 |
|
|
|| (ir[15:0] == 16'b0000_001_0_00_111100)
|
2568 |
|
|
|| (ir[15:0] == 16'b0000_101_0_00_111100));
|
2569 |
|
|
|
2570 |
12 |
alfik |
endmodule
|
2571 |
|
|
|
2572 |
|
|
/***********************************************************************************************************************
|
2573 |
|
|
* Condition
|
2574 |
|
|
**********************************************************************************************************************/
|
2575 |
|
|
|
2576 |
|
|
/*! \brief Condition tests.
|
2577 |
|
|
*
|
2578 |
|
|
* The condition module implements the condition tests of the MC68000. Its inputs are the condition codes
|
2579 |
|
|
* and the currently selected test. The output is binary: the test is true or false. The output of the condition module
|
2580 |
|
|
* is an input to the microcode_branch module, that decides which microcode word to execute next.
|
2581 |
|
|
*/
|
2582 |
|
|
module condition(
|
2583 |
|
|
input [3:0] cond,
|
2584 |
|
|
input [7:0] ccr,
|
2585 |
|
|
output condition
|
2586 |
|
|
);
|
2587 |
|
|
|
2588 |
|
|
wire C,V,Z,N;
|
2589 |
|
|
assign C = ccr[0];
|
2590 |
|
|
assign V = ccr[1];
|
2591 |
|
|
assign Z = ccr[2];
|
2592 |
|
|
assign N = ccr[3];
|
2593 |
|
|
|
2594 |
|
|
assign condition = (cond == 4'b0000) ? 1'b1 : // true
|
2595 |
|
|
(cond == 4'b0001) ? 1'b0 : // false
|
2596 |
|
|
(cond == 4'b0010) ? ~C & ~Z : // high
|
2597 |
|
|
(cond == 4'b0011) ? C | Z : // low or same
|
2598 |
|
|
(cond == 4'b0100) ? ~C : // carry clear
|
2599 |
|
|
(cond == 4'b0101) ? C : // carry set
|
2600 |
|
|
(cond == 4'b0110) ? ~Z : // not equal
|
2601 |
|
|
(cond == 4'b0111) ? Z : // equal
|
2602 |
|
|
(cond == 4'b1000) ? ~V : // overflow clear
|
2603 |
|
|
(cond == 4'b1001) ? V : // overflow set
|
2604 |
|
|
(cond == 4'b1010) ? ~N : // plus
|
2605 |
|
|
(cond == 4'b1011) ? N : // minus
|
2606 |
|
|
(cond == 4'b1100) ? (N & V) | (~N & ~V) : // greater or equal
|
2607 |
|
|
(cond == 4'b1101) ? (N & ~V) | (~N & V) : // less than
|
2608 |
|
|
(cond == 4'b1110) ? (N & V & ~Z) | (~N & ~V & ~Z) : // greater than
|
2609 |
|
|
(cond == 4'b1111) ? (Z) | (N & ~V) | (~N & V) : // less or equal
|
2610 |
|
|
1'b0;
|
2611 |
|
|
endmodule
|
2612 |
|
|
|
2613 |
|
|
/***********************************************************************************************************************
|
2614 |
|
|
* ALU
|
2615 |
|
|
**********************************************************************************************************************/
|
2616 |
|
|
|
2617 |
|
|
/*! \brief Arithmetic and Logic Unit.
|
2618 |
|
|
*
|
2619 |
|
|
* The alu module is responsible for performing all of the arithmetic and logic operations of the ao68000 processor.
|
2620 |
|
|
* It operates on two 32-bit registers: operand1 and operand2 from the registers module. The output is saved into
|
2621 |
|
|
* a result 32-bit register. This register is located in the alu module.
|
2622 |
|
|
*
|
2623 |
|
|
* The alu module also contains the status register (SR) with the condition code register. The microcode decides what
|
2624 |
|
|
* operation the alu performs.
|
2625 |
|
|
*/
|
2626 |
|
|
module alu(
|
2627 |
|
|
input clock,
|
2628 |
|
|
input reset_n,
|
2629 |
|
|
|
2630 |
|
|
// only zero bit
|
2631 |
|
|
input [31:0] address,
|
2632 |
|
|
// only ir[11:9] and ir[6]
|
2633 |
|
|
input [15:0] ir,
|
2634 |
|
|
// byte 2'b00, word 2'b01, long 2'b10
|
2635 |
13 |
alfik |
input [2:0] size,
|
2636 |
12 |
alfik |
|
2637 |
|
|
input [31:0] operand1,
|
2638 |
|
|
input [31:0] operand2,
|
2639 |
|
|
|
2640 |
|
|
input [2:0] interrupt_mask,
|
2641 |
|
|
input [4:0] alu_control,
|
2642 |
|
|
|
2643 |
|
|
output reg [15:0] sr,
|
2644 |
|
|
output reg [31:0] result,
|
2645 |
13 |
alfik |
|
2646 |
|
|
output reg alu_signal,
|
2647 |
16 |
alfik |
output alu_mult_div_ready,
|
2648 |
|
|
input [17:0] decoder_alu_reg
|
2649 |
12 |
alfik |
);
|
2650 |
|
|
|
2651 |
13 |
alfik |
//****************************************************** Altera-specific multiplication and division modules START
|
2652 |
|
|
/* Multiplication and division modules.
|
2653 |
|
|
*
|
2654 |
|
|
* Currently this module contains:
|
2655 |
|
|
* - <em>lpm_mult</em> instantiation from Altera Megafunction/LPM library,
|
2656 |
|
|
* - a sequential state machine for division written by Frederic Requin
|
2657 |
|
|
*/
|
2658 |
|
|
|
2659 |
|
|
wire mult_div_sign = ir[8];
|
2660 |
|
|
|
2661 |
|
|
// 18-2 - division calculation, 1 - waiting for result read, 0 - idle
|
2662 |
|
|
reg [4:0] div_count;
|
2663 |
|
|
reg [16:0] quotient;
|
2664 |
|
|
reg [31:0] dividend, divider;
|
2665 |
|
|
|
2666 |
|
|
// Compute the difference with borrow
|
2667 |
|
|
wire [32:0] div_diff = (dividend - divider);
|
2668 |
|
|
|
2669 |
|
|
// Overflow flag: when (quotient >= 65536) or (signed division and (quotient >= 32768 or quotient < -32768))
|
2670 |
|
|
wire div_overflow =
|
2671 |
|
|
(quotient[16] == 1'b1 ||
|
2672 |
|
|
(mult_div_sign == 1'b1 && (
|
2673 |
|
|
((operand1[31] ^ operand2[15]) == 1'b0 && quotient[15] == 1'b1) ||
|
2674 |
|
|
((operand1[31] ^ operand2[15]) == 1'b1 && quotient[15:0] > 16'd32768) )));
|
2675 |
|
|
|
2676 |
|
|
wire [15:0] div_quotient =
|
2677 |
|
|
// positive quotient
|
2678 |
|
|
(((operand1[31] ^ operand2[15]) & mult_div_sign) == 1'b0)? quotient[15:0] :
|
2679 |
|
|
// negative quotient
|
2680 |
|
|
-quotient[15:0];
|
2681 |
|
|
|
2682 |
|
|
wire [15:0] div_remainder =
|
2683 |
|
|
// positive remainder
|
2684 |
|
|
((operand1[31] & mult_div_sign) == 1'b0)? dividend[15:0] :
|
2685 |
|
|
// negative remainder
|
2686 |
|
|
-dividend[15:0];
|
2687 |
|
|
|
2688 |
|
|
always @(posedge clock or negedge reset_n) begin
|
2689 |
|
|
if(reset_n == 1'b0) begin
|
2690 |
|
|
div_count <= 5'd0;
|
2691 |
|
|
end
|
2692 |
|
|
// Cycle #0 : load the registers
|
2693 |
|
|
else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd0) begin
|
2694 |
|
|
// 17 cycles to finish + wait state
|
2695 |
|
|
div_count <= 5'd18;
|
2696 |
|
|
// Clear the quotient
|
2697 |
|
|
quotient <= 17'd0;
|
2698 |
|
|
|
2699 |
|
|
// Unsigned divide or positive numerator
|
2700 |
|
|
if ((!mult_div_sign) || (!operand1[31])) dividend <= operand1;
|
2701 |
|
|
// Negative numerator
|
2702 |
|
|
else dividend <= -operand1;
|
2703 |
|
|
|
2704 |
|
|
// Unsigned divide or positive denominator
|
2705 |
|
|
if ((!mult_div_sign) || (!operand2[15])) divider <= {operand2[15:0],16'd0};
|
2706 |
|
|
// Negative denominator
|
2707 |
|
|
else divider <= {-operand2[15:0],16'd0};
|
2708 |
|
|
end
|
2709 |
|
|
// Cycles #1-17 : division calculation
|
2710 |
|
|
else if(div_count > 5'd1) begin
|
2711 |
|
|
// Check difference's sign
|
2712 |
|
|
if (!div_diff[32]) begin
|
2713 |
|
|
// Difference is positive : shift a one
|
2714 |
|
|
dividend <= div_diff[31:0];
|
2715 |
|
|
quotient <= {quotient[15:0], 1'b1};
|
2716 |
|
|
end
|
2717 |
|
|
else begin
|
2718 |
|
|
// Difference is negative : shift a zero
|
2719 |
|
|
quotient <= {quotient[15:0], 1'b0};
|
2720 |
|
|
end
|
2721 |
|
|
// Shift right divider
|
2722 |
|
|
divider <= {1'b0, divider[31:1]};
|
2723 |
|
|
// Count one bit
|
2724 |
|
|
div_count <= div_count - 5'd1;
|
2725 |
|
|
end
|
2726 |
|
|
// result read
|
2727 |
|
|
else if(alu_control == `ALU_MULS_MULU_DIVS_DIVU && ir[15:12] == 4'b1000 && div_count == 5'd1) begin
|
2728 |
|
|
// goto idle
|
2729 |
|
|
div_count <= div_count - 5'd1;
|
2730 |
|
|
end
|
2731 |
|
|
end
|
2732 |
|
|
|
2733 |
|
|
// MULS/MULU: 16-bit operand1[15:0] signed/unsigned * operand2[15:0] signed/unsigned = 32-bit result signed/unsigned
|
2734 |
|
|
// Optimization by Frederic Requin
|
2735 |
|
|
wire [33:0] mult_result;
|
2736 |
|
|
|
2737 |
|
|
lpm_mult muls(
|
2738 |
|
|
.clock (clock),
|
2739 |
|
|
.dataa ({operand1[15] & mult_div_sign, operand1[15:0]}),
|
2740 |
|
|
.datab ({operand2[15] & mult_div_sign, operand2[15:0]}),
|
2741 |
|
|
.result (mult_result)
|
2742 |
|
|
);
|
2743 |
|
|
defparam
|
2744 |
|
|
muls.lpm_widtha = 17,
|
2745 |
|
|
muls.lpm_widthb = 17,
|
2746 |
|
|
muls.lpm_widthp = 34,
|
2747 |
|
|
muls.lpm_representation = "SIGNED",
|
2748 |
|
|
muls.lpm_pipeline = 1;
|
2749 |
|
|
|
2750 |
|
|
// multiplication ready in one cycle, division ready when div_count in waiting or idle state
|
2751 |
|
|
assign alu_mult_div_ready = (div_count == 5'd1 || div_count == 5'd0);
|
2752 |
|
|
|
2753 |
12 |
alfik |
//****************************************************** Altera-specific multiplication and division modules END
|
2754 |
|
|
|
2755 |
|
|
// ALU internal defines
|
2756 |
13 |
alfik |
`define Sm ((size[0] == 1'b1) ? operand2[7] : (size[1] == 1'b1) ? operand2[15] : operand2[31])
|
2757 |
12 |
alfik |
|
2758 |
13 |
alfik |
`define Dm ((size[0] == 1'b1) ? operand1[7] : (size[1] == 1'b1) ? operand1[15] : operand1[31])
|
2759 |
12 |
alfik |
|
2760 |
13 |
alfik |
`define Rm ((size[0] == 1'b1) ? result[7] : (size[1] == 1'b1) ? result[15] : result[31])
|
2761 |
12 |
alfik |
|
2762 |
13 |
alfik |
`define Z ((size[0] == 1'b1) ? (result[7:0] == 8'b0) : (size[1] == 1'b1) ? (result[15:0] == 16'b0) : (result[31:0] == 32'b0))
|
2763 |
12 |
alfik |
|
2764 |
|
|
// ALU operations
|
2765 |
|
|
|
2766 |
|
|
reg [2:0] interrupt_mask_copy;
|
2767 |
|
|
reg was_interrupt;
|
2768 |
|
|
|
2769 |
16 |
alfik |
// Bit being shifted left
|
2770 |
|
|
wire lbit = (`Dm & decoder_alu_reg[10]) | (sr[4] & decoder_alu_reg[11]);
|
2771 |
|
|
// Bit being shifted right
|
2772 |
|
|
wire rbit = (`Dm & decoder_alu_reg[12]) | (operand1[0] & decoder_alu_reg[14]) | (sr[4] & decoder_alu_reg[15]);
|
2773 |
|
|
|
2774 |
12 |
alfik |
always @(posedge clock or negedge reset_n) begin
|
2775 |
|
|
if(reset_n == 1'b0) begin
|
2776 |
17 |
alfik |
sr <= { 1'b0, 1'b0, 1'b1, 2'b0, 3'b111, 8'b0 };
|
2777 |
|
|
result <= 32'd0;
|
2778 |
|
|
alu_signal <= 1'b0;
|
2779 |
12 |
alfik |
interrupt_mask_copy <= 3'b0;
|
2780 |
17 |
alfik |
was_interrupt <= 1'b0;
|
2781 |
12 |
alfik |
end
|
2782 |
|
|
else begin
|
2783 |
|
|
case(alu_control)
|
2784 |
|
|
`ALU_SR_SET_INTERRUPT: begin
|
2785 |
|
|
interrupt_mask_copy <= interrupt_mask[2:0];
|
2786 |
|
|
was_interrupt <= 1'b1;
|
2787 |
|
|
end
|
2788 |
|
|
|
2789 |
|
|
`ALU_SR_SET_TRAP: begin
|
2790 |
|
|
if(was_interrupt == 1'b1) begin
|
2791 |
|
|
sr <= { 1'b0, sr[14], 1'b1, sr[12:11], interrupt_mask_copy[2:0], sr[7:0] };
|
2792 |
|
|
end
|
2793 |
|
|
else begin
|
2794 |
|
|
sr <= { 1'b0, sr[14], 1'b1, sr[12:0] };
|
2795 |
|
|
end
|
2796 |
|
|
was_interrupt <= 1'b0;
|
2797 |
|
|
end
|
2798 |
|
|
|
2799 |
|
|
`ALU_MOVEP_M2R_1: begin
|
2800 |
|
|
if(ir[6] == 1'b1) result[31:24] <= operand1[7:0];
|
2801 |
|
|
else result[15:8] <= operand1[7:0];
|
2802 |
|
|
//CCR: no change
|
2803 |
|
|
end
|
2804 |
|
|
`ALU_MOVEP_M2R_2: begin
|
2805 |
|
|
if(ir[6] == 1'b1) result[23:16] <= operand1[7:0];
|
2806 |
|
|
else result[7:0] <= operand1[7:0];
|
2807 |
|
|
//CCR: no change
|
2808 |
|
|
end
|
2809 |
|
|
`ALU_MOVEP_M2R_3: begin
|
2810 |
|
|
if(ir[6] == 1'b1) result[15:8] <= operand1[7:0];
|
2811 |
|
|
//CCR: no change
|
2812 |
|
|
end
|
2813 |
|
|
`ALU_MOVEP_M2R_4: begin
|
2814 |
|
|
if(ir[6] == 1'b1) result[7:0] <= operand1[7:0];
|
2815 |
|
|
//CCR: no change
|
2816 |
|
|
end
|
2817 |
|
|
|
2818 |
|
|
|
2819 |
|
|
`ALU_MOVEP_R2M_1: begin
|
2820 |
|
|
if(ir[6] == 1'b1) result[7:0] <= operand1[31:24];
|
2821 |
|
|
else result[7:0] <= operand1[15:8];
|
2822 |
|
|
// CCR: no change
|
2823 |
|
|
end
|
2824 |
|
|
`ALU_MOVEP_R2M_2: begin
|
2825 |
|
|
if(ir[6] == 1'b1) result[7:0] <= operand1[23:16];
|
2826 |
|
|
else result[7:0] <= operand1[7:0];
|
2827 |
|
|
// CCR: no change
|
2828 |
|
|
end
|
2829 |
|
|
`ALU_MOVEP_R2M_3: begin
|
2830 |
|
|
result[7:0] <= operand1[15:8];
|
2831 |
|
|
// CCR: no change
|
2832 |
|
|
end
|
2833 |
|
|
`ALU_MOVEP_R2M_4: begin
|
2834 |
|
|
result[7:0] <= operand1[7:0];
|
2835 |
|
|
// CCR: no change
|
2836 |
|
|
end
|
2837 |
|
|
|
2838 |
|
|
`ALU_SIGN_EXTEND: begin
|
2839 |
|
|
// move operand1 with sign-extension to result
|
2840 |
13 |
alfik |
if(size[1] == 1'b1) begin
|
2841 |
12 |
alfik |
result <= { {16{operand1[15]}}, operand1[15:0] };
|
2842 |
|
|
end
|
2843 |
|
|
else begin
|
2844 |
|
|
result <= operand1;
|
2845 |
|
|
end
|
2846 |
|
|
// CCR: no change
|
2847 |
|
|
end
|
2848 |
|
|
|
2849 |
|
|
`ALU_ARITHMETIC_LOGIC: begin
|
2850 |
|
|
|
2851 |
|
|
// OR,OR to mem,OR to Dn
|
2852 |
16 |
alfik |
if(decoder_alu_reg[0]) result[31:0] = operand1[31:0] | operand2[31:0];
|
2853 |
12 |
alfik |
// AND,AND to mem,AND to Dn
|
2854 |
16 |
alfik |
else if(decoder_alu_reg[1]) result[31:0] = operand1[31:0] & operand2[31:0];
|
2855 |
12 |
alfik |
// EORI,EOR
|
2856 |
16 |
alfik |
else if(decoder_alu_reg[2]) result[31:0] = operand1[31:0] ^ operand2[31:0];
|
2857 |
12 |
alfik |
// ADD,ADD to mem,ADD to Dn,ADDQ
|
2858 |
16 |
alfik |
else if(decoder_alu_reg[3]) result[31:0] = operand1[31:0] + operand2[31:0];
|
2859 |
12 |
alfik |
// SUBI,CMPI,CMPM,SUB to mem,SUB to Dn,CMP,SUBQ
|
2860 |
16 |
alfik |
else if(decoder_alu_reg[4] | decoder_alu_reg[5]) result[31:0] = operand1[31:0] - operand2[31:0];
|
2861 |
12 |
alfik |
|
2862 |
|
|
// Z
|
2863 |
|
|
sr[2] <= `Z;
|
2864 |
|
|
// N
|
2865 |
|
|
sr[3] <= `Rm;
|
2866 |
|
|
|
2867 |
|
|
// CMPI,CMPM,CMP
|
2868 |
16 |
alfik |
if(decoder_alu_reg[5]) begin
|
2869 |
12 |
alfik |
// C,V
|
2870 |
|
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
2871 |
|
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
2872 |
|
|
// X not affected
|
2873 |
|
|
end
|
2874 |
|
|
// ADDI,ADD to mem,ADD to Dn,ADDQ
|
2875 |
16 |
alfik |
else if(decoder_alu_reg[3]) begin
|
2876 |
12 |
alfik |
// C,X,V
|
2877 |
|
|
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
|
2878 |
|
|
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
|
2879 |
|
|
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
|
2880 |
|
|
end
|
2881 |
|
|
// SUBI,SUB to mem,SUB to Dn,SUBQ
|
2882 |
16 |
alfik |
else if(decoder_alu_reg[4]) begin
|
2883 |
12 |
alfik |
// C,X,V
|
2884 |
|
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
2885 |
|
|
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
2886 |
|
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
2887 |
|
|
end
|
2888 |
|
|
// ANDI,EORI,ORI,EOR,OR to mem,AND to mem,OR to Dn,AND to Dn
|
2889 |
|
|
else begin
|
2890 |
|
|
// C,V
|
2891 |
|
|
sr[0] <= 1'b0;
|
2892 |
|
|
sr[1] <= 1'b0;
|
2893 |
|
|
// X not affected
|
2894 |
|
|
end
|
2895 |
|
|
end
|
2896 |
17 |
alfik |
|
2897 |
|
|
`ALU_ABCD_SBCD_ADDX_SUBX_prepare: begin
|
2898 |
12 |
alfik |
// ABCD
|
2899 |
17 |
alfik |
if( ir[14:12] == 3'b100) begin
|
2900 |
12 |
alfik |
result[13:8] = {1'b0, operand1[3:0]} + {1'b0, operand2[3:0]} + {4'b0, sr[4]};
|
2901 |
|
|
result[19:14] = {1'b0, operand1[7:4]} + {1'b0, operand2[7:4]};
|
2902 |
|
|
|
2903 |
|
|
result[31:23] = operand1[7:0] + operand2[7:0] + {7'b0, sr[4]};
|
2904 |
|
|
|
2905 |
|
|
result[13:8] = (result[13:8] > 6'd9) ? (result[13:8] + 6'd6) : result[13:8];
|
2906 |
17 |
alfik |
end
|
2907 |
|
|
// SBCD
|
2908 |
|
|
else if( ir[14:12] == 3'b000 ) begin
|
2909 |
|
|
result[13:8] = 6'd32 + {2'b0, operand1[3:0]} - {2'b0, operand2[3:0]} - {5'b0, sr[4]};
|
2910 |
|
|
result[19:14] = 6'd32 + {2'b0, operand1[7:4]} - {2'b0, operand2[7:4]};
|
2911 |
|
|
|
2912 |
|
|
result[31:23] = operand1[7:0] - operand2[7:0] - {7'b0, sr[4]};
|
2913 |
|
|
|
2914 |
|
|
result[13:8] = (result[13:8] < 6'd32) ? (result[13:8] - 6'd6) : result[13:8];
|
2915 |
|
|
end
|
2916 |
|
|
end
|
2917 |
|
|
|
2918 |
|
|
`ALU_ABCD_SBCD_ADDX_SUBX: begin
|
2919 |
|
|
// ABCD
|
2920 |
|
|
if( ir[14:12] == 3'b100) begin
|
2921 |
12 |
alfik |
result[19:14] = (result[13:8] > 6'h1F) ? (result[19:14] + 6'd2) :
|
2922 |
|
|
(result[13:8] > 6'h0F) ? (result[19:14] + 6'd1) :
|
2923 |
|
|
result[19:14];
|
2924 |
|
|
result[19:14] = (result[19:14] > 6'd9) ? (result[19:14] + 6'd6) : result[19:14];
|
2925 |
|
|
|
2926 |
|
|
result[7:4] = result[17:14];
|
2927 |
|
|
result[3:0] = result[11:8];
|
2928 |
16 |
alfik |
|
2929 |
12 |
alfik |
// C
|
2930 |
|
|
sr[0] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
|
2931 |
|
|
// X = C
|
2932 |
|
|
sr[4] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0;
|
2933 |
|
|
|
2934 |
|
|
// V
|
2935 |
|
|
sr[1] <= (result[30] == 1'b0 && result[7] == 1'b1) ? 1'b1 : 1'b0;
|
2936 |
|
|
end
|
2937 |
|
|
// SBCD
|
2938 |
|
|
else if( ir[14:12] == 3'b000 ) begin
|
2939 |
|
|
result[19:14] = (result[13:8] < 6'd16) ? (result[19:14] - 6'd2) :
|
2940 |
|
|
(result[13:8] < 6'd32) ? (result[19:14] - 6'd1) :
|
2941 |
|
|
result[19:14];
|
2942 |
|
|
result[19:14] = (result[19:14] < 6'd32 && result[31] == 1'b1) ? (result[19:14] - 6'd6) : result[19:14];
|
2943 |
|
|
|
2944 |
|
|
result[7:4] = result[17:14];
|
2945 |
|
|
result[3:0] = result[11:8];
|
2946 |
|
|
|
2947 |
|
|
// C
|
2948 |
|
|
sr[0] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
|
2949 |
|
|
// X = C
|
2950 |
|
|
sr[4] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0;
|
2951 |
|
|
|
2952 |
|
|
// V
|
2953 |
|
|
sr[1] <= (result[30] == 1'b1 && result[7] == 1'b0) ? 1'b1 : 1'b0;
|
2954 |
|
|
end
|
2955 |
|
|
// ADDX
|
2956 |
17 |
alfik |
else if( ir[14:12] == 3'b101 ) begin
|
2957 |
|
|
result[31:0] = operand1[31:0] + operand2[31:0] + sr[4];
|
2958 |
|
|
|
2959 |
12 |
alfik |
// C,X,V
|
2960 |
|
|
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm);
|
2961 |
|
|
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0];
|
2962 |
|
|
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm);
|
2963 |
|
|
end
|
2964 |
|
|
// SUBX
|
2965 |
17 |
alfik |
else if( ir[14:12] == 3'b001 ) begin
|
2966 |
|
|
result[31:0] = operand1[31:0] - operand2[31:0] - sr[4];
|
2967 |
|
|
|
2968 |
12 |
alfik |
// C,X,V
|
2969 |
|
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
2970 |
|
|
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
2971 |
|
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
2972 |
|
|
end
|
2973 |
17 |
alfik |
|
2974 |
|
|
// Z
|
2975 |
|
|
sr[2] <= sr[2] & `Z;
|
2976 |
|
|
// N
|
2977 |
|
|
sr[3] <= `Rm;
|
2978 |
12 |
alfik |
end
|
2979 |
|
|
|
2980 |
|
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare: begin
|
2981 |
16 |
alfik |
// 32-bit load even for 8-bit and 16-bit operations
|
2982 |
|
|
// The extra bits will be anyway discarded during register / memory write
|
2983 |
|
|
result[31:0] = operand1[31:0];
|
2984 |
|
|
|
2985 |
12 |
alfik |
// V cleared
|
2986 |
|
|
sr[1] <= 1'b0;
|
2987 |
|
|
// C for ROXL,ROXR: set to X
|
2988 |
16 |
alfik |
if(decoder_alu_reg[11] | decoder_alu_reg[15]) begin
|
2989 |
12 |
alfik |
sr[0] <= sr[4];
|
2990 |
|
|
end
|
2991 |
|
|
else begin
|
2992 |
|
|
// C cleared
|
2993 |
|
|
sr[0] <= 1'b0;
|
2994 |
|
|
end
|
2995 |
|
|
|
2996 |
|
|
// N set
|
2997 |
|
|
sr[3] <= `Rm;
|
2998 |
|
|
// Z set
|
2999 |
|
|
sr[2] <= `Z;
|
3000 |
|
|
end
|
3001 |
|
|
|
3002 |
|
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR: begin
|
3003 |
16 |
alfik |
// ASL / LSL / ROL / ROXL
|
3004 |
|
|
if (decoder_alu_reg[8] | decoder_alu_reg[9] | decoder_alu_reg[10] | decoder_alu_reg[11]) begin
|
3005 |
|
|
result[31:0] = {operand1[30:0], lbit};
|
3006 |
12 |
alfik |
|
3007 |
16 |
alfik |
sr[0] <= `Dm; // C for ASL / LSL / ROL / ROXL
|
3008 |
|
|
if (decoder_alu_reg[8])
|
3009 |
|
|
sr[1] <= (sr[1] == 1'b0)? (`Rm != `Dm) : 1'b1; // V for ASL
|
3010 |
|
|
else
|
3011 |
|
|
sr[1] <= 1'b0; // V for LSL / ROL / ROXL
|
3012 |
|
|
|
3013 |
|
|
if (!decoder_alu_reg[10]) sr[4] <= `Dm; // X for ASL / LSL / ROXL
|
3014 |
12 |
alfik |
end
|
3015 |
16 |
alfik |
// ASR / LSR / ROR / ROXR
|
3016 |
|
|
else begin
|
3017 |
|
|
result[6:0] = operand1[7:1];
|
3018 |
|
|
result[7] = (size[0]) ? rbit : operand1[8];
|
3019 |
|
|
result[14:8] = operand1[15:9];
|
3020 |
|
|
result[15] = (size[1]) ? rbit : operand1[16];
|
3021 |
|
|
result[30:16] = operand1[31:17];
|
3022 |
|
|
result[31] = rbit;
|
3023 |
|
|
sr[0] <= operand1[0]; // C for ASR / LSR / ROR / ROXR
|
3024 |
|
|
sr[1] <= 1'b0; // V for ASR / LSR / ROR / ROXR
|
3025 |
|
|
if (!decoder_alu_reg[14]) sr[4] <= operand1[0]; // X for ASR / LSR / ROXR
|
3026 |
12 |
alfik |
end
|
3027 |
|
|
|
3028 |
|
|
// N set
|
3029 |
|
|
sr[3] <= `Rm;
|
3030 |
|
|
// Z set
|
3031 |
|
|
sr[2] <= `Z;
|
3032 |
|
|
end
|
3033 |
|
|
|
3034 |
|
|
`ALU_MOVE: begin
|
3035 |
|
|
result = operand1;
|
3036 |
|
|
|
3037 |
|
|
// X not affected
|
3038 |
|
|
// C cleared
|
3039 |
|
|
sr[0] <= 1'b0;
|
3040 |
|
|
// V cleared
|
3041 |
|
|
sr[1] <= 1'b0;
|
3042 |
|
|
|
3043 |
|
|
// N set
|
3044 |
|
|
sr[3] <= `Rm;
|
3045 |
|
|
// Z set
|
3046 |
|
|
sr[2] <= `Z;
|
3047 |
|
|
end
|
3048 |
|
|
|
3049 |
|
|
`ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ: begin
|
3050 |
|
|
// ADDA: 1101
|
3051 |
|
|
// CMPA: 1011
|
3052 |
|
|
// SUBA: 1001
|
3053 |
|
|
// ADDQ,SUBQ: 0101 xxx0,1
|
3054 |
|
|
// operation requires that operand2 was sign extended
|
3055 |
|
|
|
3056 |
|
|
// ADDA,ADDQ
|
3057 |
16 |
alfik |
if(decoder_alu_reg[6]) result[31:0] = operand1[31:0] + operand2[31:0];
|
3058 |
12 |
alfik |
// SUBA,CMPA,SUBQ
|
3059 |
16 |
alfik |
else result[31:0] = operand1[31:0] - operand2[31:0];
|
3060 |
|
|
|
3061 |
12 |
alfik |
// for CMPA
|
3062 |
|
|
if( ir[15:12] == 4'b1011 ) begin
|
3063 |
|
|
// Z
|
3064 |
|
|
sr[2] <= `Z;
|
3065 |
|
|
// N
|
3066 |
|
|
sr[3] <= `Rm;
|
3067 |
|
|
|
3068 |
|
|
// C,V
|
3069 |
|
|
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
3070 |
|
|
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
3071 |
|
|
// X not affected
|
3072 |
|
|
end
|
3073 |
|
|
// for ADDA,SUBA,ADDQ,SUBQ: ccr not affected
|
3074 |
|
|
end
|
3075 |
|
|
|
3076 |
|
|
`ALU_CHK: begin
|
3077 |
|
|
result[15:0] = operand1[15:0] - operand2[15:0];
|
3078 |
|
|
|
3079 |
|
|
// undocumented behavior: Z flag, see 68knotes.txt
|
3080 |
|
|
//sr[2] <= (operand1[15:0] == 16'b0) ? 1'b1 : 1'b0;
|
3081 |
|
|
// undocumented behavior: C,V flags, see 68knotes.txt
|
3082 |
|
|
//sr[0] <= 1'b0;
|
3083 |
|
|
//sr[1] <= 1'b0;
|
3084 |
|
|
|
3085 |
|
|
// C,X,V
|
3086 |
|
|
// sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm);
|
3087 |
|
|
// sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0];
|
3088 |
|
|
// sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm);
|
3089 |
|
|
// +: 0-1, 0-0=0, 1-1=0
|
3090 |
|
|
// -: 0-0=1, 1-0, 1-1=1
|
3091 |
|
|
// operand1 - operand2 > 0
|
3092 |
|
|
if( operand1[15:0] != operand2[15:0] && ((~`Dm & `Sm) | (~`Dm & ~`Sm & ~`Rm) | (`Dm & `Sm & ~`Rm)) == 1'b1 ) begin
|
3093 |
|
|
// clear N
|
3094 |
|
|
sr[3] <= 1'b0;
|
3095 |
13 |
alfik |
alu_signal <= 1'b1;
|
3096 |
12 |
alfik |
end
|
3097 |
|
|
// operand1 < 0
|
3098 |
|
|
else if( operand1[15] == 1'b1 ) begin
|
3099 |
|
|
// set N
|
3100 |
|
|
sr[3] <= 1'b1;
|
3101 |
13 |
alfik |
alu_signal <= 1'b1;
|
3102 |
12 |
alfik |
end
|
3103 |
|
|
// no trap
|
3104 |
|
|
else begin
|
3105 |
|
|
// N undefined: not affected
|
3106 |
13 |
alfik |
alu_signal <= 1'b0;
|
3107 |
12 |
alfik |
end
|
3108 |
|
|
|
3109 |
|
|
// X not affected
|
3110 |
|
|
end
|
3111 |
|
|
|
3112 |
13 |
alfik |
`ALU_MULS_MULU_DIVS_DIVU: begin
|
3113 |
12 |
alfik |
|
3114 |
|
|
// division by 0
|
3115 |
13 |
alfik |
if(ir[15:12] == 4'b1000 && operand2[15:0] == 16'b0) begin
|
3116 |
12 |
alfik |
// X not affected
|
3117 |
|
|
// C cleared
|
3118 |
|
|
sr[0] <= 1'b0;
|
3119 |
|
|
// V,Z,N undefined: cleared
|
3120 |
|
|
sr[1] <= 1'b0;
|
3121 |
|
|
sr[2] <= 1'b0;
|
3122 |
|
|
sr[3] <= 1'b0;
|
3123 |
|
|
|
3124 |
|
|
// set trap
|
3125 |
13 |
alfik |
alu_signal <= 1'b1;
|
3126 |
12 |
alfik |
end
|
3127 |
13 |
alfik |
// division in idle state
|
3128 |
|
|
else if(ir[15:12] == 4'b1000 && div_count == 5'd0) begin
|
3129 |
|
|
alu_signal <= 1'b0;
|
3130 |
|
|
end
|
3131 |
12 |
alfik |
// division overflow: divu, divs
|
3132 |
13 |
alfik |
else if(ir[15:12] == 4'b1000 && div_overflow == 1'b1) begin
|
3133 |
12 |
alfik |
// X not affected
|
3134 |
|
|
// C cleared
|
3135 |
|
|
sr[0] <= 1'b0;
|
3136 |
|
|
// V set
|
3137 |
|
|
sr[1] <= 1'b1;
|
3138 |
|
|
// Z,N undefined: cleared and set
|
3139 |
|
|
sr[2] <= 1'b0;
|
3140 |
|
|
sr[3] <= 1'b1;
|
3141 |
|
|
|
3142 |
|
|
// set trap
|
3143 |
13 |
alfik |
alu_signal <= 1'b1;
|
3144 |
12 |
alfik |
end
|
3145 |
|
|
// division
|
3146 |
|
|
else if( ir[15:12] == 4'b1000 ) begin
|
3147 |
13 |
alfik |
result[31:0] <= {div_remainder, div_quotient};
|
3148 |
|
|
|
3149 |
12 |
alfik |
// X not affected
|
3150 |
|
|
// C cleared
|
3151 |
|
|
sr[0] <= 1'b0;
|
3152 |
|
|
// V cleared
|
3153 |
|
|
sr[1] <= 1'b0;
|
3154 |
|
|
// Z
|
3155 |
13 |
alfik |
sr[2] <= (div_quotient == 16'b0);
|
3156 |
12 |
alfik |
// N
|
3157 |
13 |
alfik |
sr[3] <= (div_quotient[15] == 1'b1);
|
3158 |
12 |
alfik |
|
3159 |
|
|
// set trap
|
3160 |
13 |
alfik |
alu_signal <= 1'b0;
|
3161 |
12 |
alfik |
end
|
3162 |
|
|
// multiplication
|
3163 |
|
|
else if( ir[15:12] == 4'b1100 ) begin
|
3164 |
13 |
alfik |
result[31:0] <= mult_result[31:0];
|
3165 |
12 |
alfik |
|
3166 |
|
|
// X not affected
|
3167 |
|
|
// C cleared
|
3168 |
|
|
sr[0] <= 1'b0;
|
3169 |
|
|
// V cleared
|
3170 |
|
|
sr[1] <= 1'b0;
|
3171 |
|
|
// Z
|
3172 |
13 |
alfik |
sr[2] <= (mult_result[31:0] == 32'b0);
|
3173 |
12 |
alfik |
// N
|
3174 |
13 |
alfik |
sr[3] <= (mult_result[31] == 1'b1);
|
3175 |
12 |
alfik |
|
3176 |
|
|
// set trap
|
3177 |
13 |
alfik |
alu_signal <= 1'b0;
|
3178 |
12 |
alfik |
end
|
3179 |
|
|
end
|
3180 |
|
|
|
3181 |
|
|
|
3182 |
|
|
`ALU_BCHG_BCLR_BSET_BTST: begin // 97 LE
|
3183 |
|
|
// byte
|
3184 |
|
|
if( ir[5:3] != 3'b000 ) begin
|
3185 |
|
|
sr[2] <= ~(operand1[ operand2[2:0] ]);
|
3186 |
|
|
result = operand1;
|
3187 |
|
|
result[ operand2[2:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[2:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
|
3188 |
|
|
end
|
3189 |
|
|
// long
|
3190 |
|
|
else if( ir[5:3] == 3'b000 ) begin
|
3191 |
|
|
sr[2] <= ~(operand1[ operand2[4:0] ]);
|
3192 |
|
|
result = operand1;
|
3193 |
|
|
result[ operand2[4:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[4:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1;
|
3194 |
|
|
end
|
3195 |
|
|
|
3196 |
|
|
// C,V,N,X not affected
|
3197 |
|
|
end
|
3198 |
|
|
|
3199 |
|
|
`ALU_TAS: begin
|
3200 |
|
|
result[7:0] <= { 1'b1, operand1[6:0] };
|
3201 |
|
|
|
3202 |
|
|
// X not affected
|
3203 |
|
|
// C cleared
|
3204 |
|
|
sr[0] <= 1'b0;
|
3205 |
|
|
// V cleared
|
3206 |
|
|
sr[1] <= 1'b0;
|
3207 |
|
|
|
3208 |
|
|
// N set
|
3209 |
|
|
sr[3] <= (operand1[7] == 1'b1);
|
3210 |
|
|
// Z set
|
3211 |
|
|
sr[2] <= (operand1[7:0] == 8'b0);
|
3212 |
|
|
end
|
3213 |
|
|
|
3214 |
|
|
|
3215 |
|
|
`ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT: begin
|
3216 |
13 |
alfik |
// NEGX / CLR / NEG / NOT
|
3217 |
16 |
alfik |
// Optimization thanks to Frederic Requin
|
3218 |
13 |
alfik |
if ((ir[11:8] == 4'b0000) || (ir[11:8] == 4'b0010) || (ir[11:8] == 4'b0100) || (ir[11:8] == 4'b0110))
|
3219 |
|
|
result = 32'b0 - (operand1[31:0] & {32{ir[10] | ~ir[9]}}) - ((sr[4] & ~ir[10] & ~ir[9]) | (ir[10] & ir[9]));
|
3220 |
12 |
alfik |
// NBCD
|
3221 |
|
|
else if( ir[11:6] == 6'b1000_00 ) begin
|
3222 |
|
|
result[3:0] = 5'd25 - operand1[3:0];
|
3223 |
|
|
result[7:4] = (operand1[3:0] > 4'd9) ? (5'd24 - operand1[7:4]) : (5'd25 - operand1[7:4]);
|
3224 |
|
|
|
3225 |
|
|
if(sr[4] == 1'b0 && result[3:0] == 4'd9 && result[7:4] == 4'd9) begin
|
3226 |
|
|
result[3:0] = 4'd0;
|
3227 |
|
|
result[7:4] = 4'd0;
|
3228 |
|
|
end
|
3229 |
|
|
else if(sr[4] == 1'b0 && (result[3:0] == 4'd9 || result[3:0] == 4'd15)) begin
|
3230 |
|
|
result[3:0] = 4'd0;
|
3231 |
|
|
result[7:4] = result[7:4] + 4'd1;
|
3232 |
|
|
end
|
3233 |
|
|
else if(sr[4] == 1'b0) begin
|
3234 |
|
|
result[3:0] = result[3:0] + 4'd1;
|
3235 |
|
|
end
|
3236 |
|
|
|
3237 |
|
|
//V undefined: unchanged
|
3238 |
|
|
//Z
|
3239 |
|
|
sr[2] <= sr[2] & `Z;
|
3240 |
|
|
//C,X
|
3241 |
|
|
sr[0] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1;
|
3242 |
|
|
sr[4] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1; //=C
|
3243 |
|
|
end
|
3244 |
|
|
// SWAP
|
3245 |
|
|
else if( ir[11:6] == 6'b1000_01 ) result = { operand1[15:0], operand1[31:16] };
|
3246 |
|
|
// EXT byte to word
|
3247 |
|
|
else if( ir[11:6] == 6'b1000_10 ) result = { result[31:16], {8{operand1[7]}}, operand1[7:0] };
|
3248 |
|
|
// EXT word to long
|
3249 |
|
|
else if( ir[11:6] == 6'b1000_11 ) result = { {16{operand1[15]}}, operand1[15:0] };
|
3250 |
|
|
|
3251 |
|
|
// N set if negative else clear
|
3252 |
|
|
sr[3] <= `Rm;
|
3253 |
|
|
|
3254 |
|
|
// CLR,NOT,SWAP,EXT
|
3255 |
|
|
if( ir[11:8] == 4'b0010 || ir[11:8] == 4'b0110 || ir[11:6] == 6'b1000_01 || ir[11:7] == 5'b1000_1 ) begin
|
3256 |
|
|
// X not affected
|
3257 |
|
|
// C,V cleared
|
3258 |
|
|
sr[0] <= 1'b0;
|
3259 |
|
|
sr[1] <= 1'b0;
|
3260 |
|
|
// Z set
|
3261 |
|
|
sr[2] <= `Z;
|
3262 |
|
|
end
|
3263 |
|
|
// NEGX
|
3264 |
|
|
else if( ir[11:8] == 4'b0000 ) begin
|
3265 |
|
|
// C set if borrow
|
3266 |
|
|
sr[0] <= `Dm | `Rm;
|
3267 |
|
|
// X=C
|
3268 |
|
|
sr[4] <= `Dm | `Rm;
|
3269 |
|
|
// V set if overflow
|
3270 |
|
|
sr[1] <= `Dm & `Rm;
|
3271 |
|
|
// Z cleared if nonzero else unchanged
|
3272 |
|
|
sr[2] <= sr[2] & `Z;
|
3273 |
|
|
end
|
3274 |
|
|
// NEG
|
3275 |
|
|
else if( ir[11:8] == 4'b0100 ) begin
|
3276 |
|
|
// C clear if zero else set
|
3277 |
|
|
sr[0] <= `Dm | `Rm;
|
3278 |
|
|
// X=C
|
3279 |
|
|
sr[4] <= `Dm | `Rm;
|
3280 |
|
|
// V set if overflow
|
3281 |
|
|
sr[1] <= `Dm & `Rm;
|
3282 |
|
|
// Z set if zero else clear
|
3283 |
|
|
sr[2] <= `Z;
|
3284 |
|
|
end
|
3285 |
|
|
end
|
3286 |
|
|
|
3287 |
|
|
|
3288 |
|
|
`ALU_SIMPLE_LONG_ADD: begin
|
3289 |
|
|
result <= operand1[31:0] + operand2[31:0];
|
3290 |
|
|
|
3291 |
|
|
// CCR not affected
|
3292 |
|
|
end
|
3293 |
|
|
|
3294 |
|
|
`ALU_SIMPLE_LONG_SUB: begin
|
3295 |
|
|
result <= operand1[31:0] - operand2[31:0];
|
3296 |
|
|
|
3297 |
|
|
// CCR not affected
|
3298 |
|
|
end
|
3299 |
|
|
|
3300 |
|
|
`ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR: begin
|
3301 |
|
|
|
3302 |
|
|
// MOVE TO SR,RTE,STOP,ORI to SR,ANDI to SR,EORI to SR
|
3303 |
16 |
alfik |
if(decoder_alu_reg[16]) sr <= { operand1[15], 1'b0, operand1[13], 2'b0, operand1[10:8], 3'b0, operand1[4:0] };
|
3304 |
12 |
alfik |
// MOVE TO CCR,RTR,ORI to CCR,ANDI to CCR,EORI to CCR
|
3305 |
16 |
alfik |
else sr <= { sr[15:8], 3'b0, operand1[4:0] };
|
3306 |
12 |
alfik |
end
|
3307 |
|
|
|
3308 |
|
|
`ALU_SIMPLE_MOVE: begin
|
3309 |
|
|
result <= operand1;
|
3310 |
|
|
|
3311 |
|
|
// CCR not affected
|
3312 |
|
|
end
|
3313 |
|
|
|
3314 |
|
|
`ALU_LINK_MOVE: begin
|
3315 |
|
|
if(ir[3:0] == 3'b111) begin
|
3316 |
|
|
result <= operand1 - 32'd4;
|
3317 |
|
|
end
|
3318 |
|
|
else begin
|
3319 |
|
|
result <= operand1;
|
3320 |
|
|
end
|
3321 |
|
|
|
3322 |
|
|
// CCR not affected
|
3323 |
|
|
end
|
3324 |
|
|
|
3325 |
|
|
endcase
|
3326 |
|
|
end
|
3327 |
|
|
end
|
3328 |
|
|
|
3329 |
|
|
endmodule
|
3330 |
|
|
|
3331 |
|
|
/***********************************************************************************************************************
|
3332 |
|
|
* Microcode branch
|
3333 |
|
|
**********************************************************************************************************************/
|
3334 |
|
|
|
3335 |
|
|
/*! \brief Select the next microcode word to execute.
|
3336 |
|
|
*
|
3337 |
|
|
* The microcode_branch module is responsible for selecting the next microcode word to execute. This decision is based
|
3338 |
|
|
* on the value of the current microcode word, the value of the interrupt privilege level, the state of the current
|
3339 |
|
|
* bus cycle and other internal signals.
|
3340 |
|
|
*
|
3341 |
|
|
* The microcode_branch module implements a simple stack for the microcode addresses. This makes it possible to call
|
3342 |
|
|
* subroutines inside the microcode.
|
3343 |
|
|
*/
|
3344 |
|
|
module microcode_branch(
|
3345 |
|
|
input clock,
|
3346 |
|
|
input reset_n,
|
3347 |
|
|
|
3348 |
13 |
alfik |
input [4:0] movem_loop,
|
3349 |
|
|
input [15:0] movem_reg,
|
3350 |
|
|
input [31:0] operand2,
|
3351 |
|
|
input alu_signal,
|
3352 |
|
|
input alu_mult_div_ready,
|
3353 |
|
|
input condition,
|
3354 |
|
|
input [31:0] result,
|
3355 |
|
|
input overflow,
|
3356 |
|
|
input stop_flag,
|
3357 |
|
|
input [15:0] ir,
|
3358 |
|
|
input [7:0] decoder_trap,
|
3359 |
|
|
input trace_flag,
|
3360 |
|
|
input group_0_flag,
|
3361 |
|
|
input [2:0] interrupt_mask,
|
3362 |
12 |
alfik |
|
3363 |
13 |
alfik |
input [8:0] load_ea,
|
3364 |
|
|
input [8:0] perform_ea_read,
|
3365 |
|
|
input [8:0] perform_ea_write,
|
3366 |
|
|
input [8:0] save_ea,
|
3367 |
|
|
input [8:0] decoder_micropc,
|
3368 |
12 |
alfik |
|
3369 |
13 |
alfik |
input prefetch_ir_valid_32,
|
3370 |
|
|
input prefetch_ir_valid,
|
3371 |
|
|
input jmp_address_trap,
|
3372 |
|
|
input jmp_bus_trap,
|
3373 |
|
|
input finished,
|
3374 |
12 |
alfik |
|
3375 |
13 |
alfik |
input [3:0] branch_control,
|
3376 |
|
|
input [3:0] branch_offset,
|
3377 |
|
|
output [8:0] micro_pc
|
3378 |
12 |
alfik |
);
|
3379 |
|
|
|
3380 |
|
|
reg [8:0] micro_pc_0 = 9'd0;
|
3381 |
|
|
reg [8:0] micro_pc_1;
|
3382 |
|
|
reg [8:0] micro_pc_2;
|
3383 |
|
|
reg [8:0] micro_pc_3;
|
3384 |
|
|
|
3385 |
|
|
assign micro_pc =
|
3386 |
|
|
(reset_n == 1'b0) ? 9'd0 :
|
3387 |
|
|
(jmp_address_trap == 1'b1 || jmp_bus_trap == 1'b1) ? `MICROPC_ADDRESS_BUS_TRAP :
|
3388 |
|
|
( (branch_control == `BRANCH_movem_loop && movem_loop == 5'b10000) ||
|
3389 |
|
|
(branch_control == `BRANCH_movem_reg && movem_reg[0] == 0) ||
|
3390 |
|
|
(branch_control == `BRANCH_operand2 && operand2[5:0] == 6'b0) ||
|
3391 |
13 |
alfik |
(branch_control == `BRANCH_alu_signal && alu_signal == 1'b0) ||
|
3392 |
|
|
(branch_control == `BRANCH_alu_mult_div_ready && alu_mult_div_ready == 1'b1) ||
|
3393 |
12 |
alfik |
(branch_control == `BRANCH_condition_0 && condition == 1'b0) ||
|
3394 |
|
|
(branch_control == `BRANCH_condition_1 && condition == 1'b1) ||
|
3395 |
|
|
(branch_control == `BRANCH_result && result[15:0] == 16'hFFFF) ||
|
3396 |
|
|
(branch_control == `BRANCH_V && overflow == 1'b0) ||
|
3397 |
|
|
(branch_control == `BRANCH_movep_16 && ir[6] == 1'b0) ||
|
3398 |
|
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && stop_flag == 1'b1) ||
|
3399 |
|
|
(branch_control == `BRANCH_ir && ir[7:0] != 8'b0) ||
|
3400 |
|
|
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask != 3'b000) ||
|
3401 |
|
|
(branch_control == `BRANCH_group_0_flag && group_0_flag == 1'b0)
|
3402 |
|
|
) ? micro_pc_0 + { 5'd0, branch_offset } :
|
3403 |
|
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0) ? decoder_micropc :
|
3404 |
|
|
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP :
|
3405 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_jump_to_main_loop) ? `MICROPC_MAIN_LOOP :
|
3406 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ? load_ea :
|
3407 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_read) ? perform_ea_read :
|
3408 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_write) ? perform_ea_write :
|
3409 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ? save_ea :
|
3410 |
|
|
|
3411 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) ? load_ea :
|
3412 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) ? perform_ea_read :
|
3413 |
|
|
|
3414 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_write) ? perform_ea_write :
|
3415 |
|
|
|
3416 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_trap) ? `MICROPC_TRAP_ENTRY :
|
3417 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_return) ? micro_pc_1 :
|
3418 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_interrupt_mask && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP :
|
3419 |
|
|
( (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_finished && finished == 1'b0) ||
|
3420 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid && prefetch_ir_valid == 1'b0) ||
|
3421 |
|
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid_32 && prefetch_ir_valid_32 == 1'b0) ||
|
3422 |
|
|
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b0)
|
3423 |
|
|
) ? micro_pc_0 :
|
3424 |
|
|
micro_pc_0 + 9'd1
|
3425 |
|
|
;
|
3426 |
|
|
|
3427 |
|
|
always @(posedge clock or negedge reset_n) begin
|
3428 |
|
|
if(reset_n == 1'b0) micro_pc_0 <= 9'd0;
|
3429 |
|
|
else micro_pc_0 <= micro_pc;
|
3430 |
|
|
end
|
3431 |
|
|
|
3432 |
|
|
always @(posedge clock or negedge reset_n) begin
|
3433 |
|
|
if(reset_n == 1'b0) begin
|
3434 |
|
|
micro_pc_1 <= 9'd0;
|
3435 |
|
|
micro_pc_2 <= 9'd0;
|
3436 |
|
|
micro_pc_3 <= 9'd0;
|
3437 |
|
|
end
|
3438 |
|
|
else if(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0)
|
3439 |
|
|
begin
|
3440 |
|
|
micro_pc_1 <= micro_pc_0 + { 5'd0, branch_offset };
|
3441 |
|
|
micro_pc_2 <= micro_pc_1;
|
3442 |
|
|
micro_pc_3 <= micro_pc_2;
|
3443 |
|
|
end
|
3444 |
|
|
else if(branch_control == `BRANCH_procedure) begin
|
3445 |
|
|
if(branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) begin
|
3446 |
|
|
micro_pc_1 <= perform_ea_read;
|
3447 |
|
|
micro_pc_2 <= micro_pc_0 + 9'd1;
|
3448 |
|
|
micro_pc_3 <= micro_pc_1;
|
3449 |
|
|
end
|
3450 |
|
|
else if(branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) begin
|
3451 |
|
|
micro_pc_1 <= micro_pc_0 + 9'd1;
|
3452 |
|
|
micro_pc_2 <= micro_pc_1;
|
3453 |
|
|
micro_pc_3 <= micro_pc_2;
|
3454 |
|
|
end
|
3455 |
|
|
else if(branch_offset == `PROCEDURE_call_write && save_ea != 9'd0) begin
|
3456 |
|
|
micro_pc_1 <= save_ea;
|
3457 |
|
|
micro_pc_2 <= micro_pc_1;
|
3458 |
|
|
micro_pc_3 <= micro_pc_2;
|
3459 |
|
|
end
|
3460 |
|
|
else if((branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ||
|
3461 |
|
|
(branch_offset == `PROCEDURE_call_perform_ea_read) ||
|
3462 |
|
|
(branch_offset == `PROCEDURE_call_perform_ea_write) ||
|
3463 |
|
|
(branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ||
|
3464 |
|
|
(branch_offset == `PROCEDURE_call_trap) )
|
3465 |
|
|
begin
|
3466 |
|
|
micro_pc_1 <= micro_pc_0 + 9'd1;
|
3467 |
|
|
micro_pc_2 <= micro_pc_1;
|
3468 |
|
|
micro_pc_3 <= micro_pc_2;
|
3469 |
|
|
end
|
3470 |
|
|
else if(branch_offset == `PROCEDURE_return) begin
|
3471 |
|
|
micro_pc_1 <= micro_pc_2;
|
3472 |
|
|
micro_pc_2 <= micro_pc_3;
|
3473 |
|
|
micro_pc_3 <= 9'd0;
|
3474 |
|
|
end
|
3475 |
|
|
else if(branch_offset == `PROCEDURE_push_micropc) begin
|
3476 |
|
|
micro_pc_1 <= micro_pc_0;
|
3477 |
|
|
micro_pc_2 <= micro_pc_1;
|
3478 |
|
|
micro_pc_3 <= micro_pc_2;
|
3479 |
|
|
end
|
3480 |
|
|
else if(branch_offset == `PROCEDURE_pop_micropc) begin
|
3481 |
|
|
micro_pc_1 <= micro_pc_2;
|
3482 |
|
|
micro_pc_2 <= micro_pc_3;
|
3483 |
|
|
micro_pc_3 <= 9'd0;
|
3484 |
|
|
end
|
3485 |
|
|
end
|
3486 |
|
|
end
|
3487 |
|
|
|
3488 |
|
|
endmodule
|