OpenCores
URL https://opencores.org/ocsvn/6809_6309_compatible_core/6809_6309_compatible_core/trunk

Subversion Repositories 6809_6309_compatible_core

[/] [6809_6309_compatible_core/] [trunk/] [rtl/] [verilog/] [regblock.v] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ale500
/*
2
 * MC6809 Register block, dual ported
3
 */
4
`include "defs.v"
5
 
6
 
7
module regblock(
8
        input wire clk_in,
9
        input wire [3:0] path_left_addr,
10
        input wire [3:0] path_right_addr,
11
        input wire [3:0] write_reg_addr,
12 5 ale500
        input wire [3:0] exg_dest_r,
13 2 ale500
        input wire [7:0] eapostbyte, // effective address post byte
14
        input wire [15:0] offset16, // up to 16 bit offset for effective address calculation
15 4 ale500
        input wire write_reg,
16 2 ale500
        input wire write_post,
17
        input wire write_pc,
18 5 ale500
        input wire write_tfr,
19
        input wire write_exg,
20 2 ale500
        input wire inc_pc,
21
        input wire inc_su, /* increments S or U */
22
        input wire dec_su, /* decrements s or u */
23
        input wire use_s, /* increments S or U */
24 6 ale500
        input wire [15:0] data_w,
25 2 ale500
        input wire [15:0] new_pc,
26 6 ale500
        input wire [7:0] CCR_in,
27 2 ale500
        input wire write_flags,
28
        input wire set_e,
29
        input wire clear_e,
30
        output wire [7:0] CCR_o,
31
        output reg [15:0] path_left_data,
32
        output reg [15:0] path_right_data,
33 9 ale500
        output wire [15:0] eamem_addr_o,
34 2 ale500
        output wire [15:0] reg_pc,
35
        output wire [7:0] reg_dp,
36
        output wire [15:0] reg_su
37
        );
38
 
39
`define ACCD { ACCA, ACCB }
40
reg [15:0] IX;
41
reg [15:0] IY;
42
reg [15:0] SU;
43
reg [15:0] SS;
44
reg [15:0] PC;
45
 
46
reg [7:0] ACCA;
47
reg [7:0] ACCB;
48
reg [7:0] DP;
49
`define CCR { eflag, fflag, hflag, intff, nff, zff, vff, cff }
50
 
51
reg eflag, fflag, hflag;
52
reg intff, nff, zff, vff, cff;
53 9 ale500
wire [15:0] eamem_addr, ea_reg_post;
54 2 ale500
 
55
assign CCR_o = `CCR;
56
assign reg_pc = PC;
57
assign reg_dp = DP;
58
assign reg_su = (use_s) ? SS:SU; /* stack pointer */
59 9 ale500
 
60
calc_ea ea(eapostbyte,
61
                        offset16,
62
                        ACCA,
63
                        ACCB,
64
                        IX,
65
                        IY,
66
                        SS,
67
                        SU,
68
                        PC,
69
                        eamem_addr,
70
                        ea_reg_post);
71
 
72
assign eamem_addr_o = eamem_addr;
73
 
74 2 ale500
// left path output, always 16 bits
75
always @(*)
76
        begin
77
                case (path_left_addr)
78 5 ale500
                        `RN_ACCA:       path_left_data = { 8'hff, ACCA };
79
                        `RN_ACCB:       path_left_data = { 8'hff, ACCB };
80 2 ale500
                        `RN_ACCD:       path_left_data = `ACCD;
81
                        `RN_IX:         path_left_data = IX;
82
                        `RN_IY:         path_left_data = IY;
83
                        `RN_U:          path_left_data = SU;
84
                        `RN_S:          path_left_data = SS;
85
                        `RN_PC:         path_left_data = PC;
86 5 ale500
                        `RN_DP:         path_left_data = { DP, DP };
87
                        `RN_CC:         path_left_data = { `CCR, `CCR };
88 2 ale500
                        default:
89 5 ale500
                                path_left_data = 16'hFFFF;
90 2 ale500
                endcase
91
        end
92
 
93
// right path output, always 16 bits
94
always @(*)
95
        begin
96
                case (path_right_addr)
97 5 ale500
                        `RN_ACCA:       path_right_data = { 8'hff, ACCA };
98
                        `RN_ACCB:       path_right_data = { 8'hff, ACCB };
99
                        `RN_ACCD:       path_right_data = `ACCD;
100
                        `RN_IX:         path_right_data = IX;
101
                        `RN_IY:         path_right_data = IY;
102
                        `RN_U:          path_right_data = SU;
103
                        `RN_S:          path_right_data = SS;
104 9 ale500
                        `RN_PC:         path_right_data = PC;
105 5 ale500
                        `RN_DP:         path_right_data = { DP, DP };
106
                        `RN_CC:         path_right_data = { `CCR, `CCR };
107 2 ale500
                        default:
108 5 ale500
                                path_right_data = 16'hFFFF;
109
                endcase
110 2 ale500
        end
111
 
112 9 ale500
wire [15:0] left, right;
113
wire [3:0] right_reg;
114
wire [15:0] pc_plus_1;
115
assign pc_plus_1 = PC + 16'h0001;
116 2 ale500
 
117 5 ale500
assign left = (write_tfr | write_exg) ? path_left_data:data_w;
118
 
119 9 ale500
assign right = (inc_pc) ? pc_plus_1:path_right_data;
120 5 ale500
 
121 9 ale500
assign right_reg = (inc_pc | write_pc) ? `RN_PC:exg_dest_r;
122 5 ale500
 
123 2 ale500
always @(posedge clk_in)
124
        begin
125 10 ale500
                if (write_exg | inc_pc)// | write_pc)
126 9 ale500
                        case (right_reg)
127
                                0: `ACCD <= right;
128
                                1: IX <= right;
129
                                2: IY <= right;
130
                                3: SU <= right;
131
                                4: SS <= right;
132
                                5: PC <= right;
133
                                8: ACCA <= right[7:0];
134
                                9: ACCB <= right[7:0];
135
                                10: `CCR <= right[7:0];
136
                                11: DP <= right[7:0];
137 5 ale500
                        endcase
138
                if (write_tfr | write_exg | write_reg)
139 2 ale500
                        case (write_reg_addr)
140 5 ale500
                                0: `ACCD <= left;
141
                                1: IX <= left;
142
                                2: IY <= left;
143
                                3: SU <= left;
144
                                4: SS <= left;
145
                                5: PC <= left;
146
                                8: ACCA <= left[7:0];
147
                                9: ACCB <= left[7:0];
148
                                10: `CCR <= left[7:0];
149
                                11: DP <= left[7:0];
150 2 ale500
                        endcase
151
                if (write_post) // write back predecrement/postincremented values
152
                        begin
153
                                case (eapostbyte[6:5])
154
                                        2'b00: IX <= ea_reg_post;
155
                                        2'b01: IY <= ea_reg_post;
156
                                        2'b10: SU <= ea_reg_post;
157
                                        2'b11: SS <= ea_reg_post;
158
                                endcase
159
                        end
160
                if (write_flags)
161
                        begin
162
                                `CCR <= CCR_in;
163
                        end
164 9 ale500
                if (set_e | clear_e) eflag <= set_e;
165
                //if (clear_e) eflag <= 0;
166 2 ale500
                if (write_pc) PC <= new_pc;
167 9 ale500
                //if (inc_pc) PC <= PC + 16'h1;
168 2 ale500
                if (inc_su)
169
                        if (use_s) SS <= SS + 16'h1;
170
                        else SU <= SU + 16'h1;
171
                if (dec_su)
172
                        if (use_s) SS <= SS - 16'h1;
173
                        else SU <= SU - 16'h1;
174
        end
175
 
176
`ifdef SIMULATION
177
initial
178
        begin
179
                PC = 16'hfffe;
180
                DP = 8'h00;
181
                IX = 16'h0;
182
                `CCR = 0;
183
                IY = 16'hA55A;
184
                SS = 16'h0f00;
185
                SU = 16'h0e00;
186
        end
187
`endif
188
endmodule
189 9 ale500
 
190
 
191
module calc_ea(
192
        input wire [7:0] eapostbyte,
193
        input wire [15:0] offset16,
194
        input wire [7:0] acca,
195
        input wire [7:0] accb,
196
        input wire [15:0] ix,
197
        input wire [15:0] iy,
198
        input wire [15:0] s,
199
        input wire [15:0] u,
200
        input wire [15:0] pc,
201
        output wire [15:0] eamem_addr_o,
202
        output wire [15:0] ea_reg_post_o
203
        );
204
 
205
reg [15:0] ea_reg, ea_reg_post, eamem_addr;
206
 
207
assign eamem_addr_o = eamem_addr;
208
assign ea_reg_post_o = ea_reg_post;
209
 
210
always @(*)
211
        begin
212
                case (eapostbyte[6:5])
213
                        2'b00: ea_reg = ix;
214
                        2'b01: ea_reg = iy;
215
                        2'b10: ea_reg = u;
216
                        2'b11: ea_reg = s;
217
                endcase
218
        end
219
// pre-decrement/postincrement
220
always @(*)
221
        begin
222
                case (eapostbyte[1:0])
223
                        2'b00: ea_reg_post = ea_reg + 16'h1;
224
                        2'b01: ea_reg_post = ea_reg + 16'h2;
225
                        2'b10: ea_reg_post = ea_reg - 16'h1;
226
                        2'b11: ea_reg_post = ea_reg - 16'h2;
227
                endcase
228
        end
229
 
230
/* EA calculation
231
 * postbyte  bytes  assembler
232
 *
233
 * 0RRnnnnn    0     n,R  n is 5 bits signed
234
 * 1RRi0000    0     ,R+
235
 * 1RRi0001    0     ,R++
236
 * 1RRi0010    0     ,-R
237
 * 1RRi0011    0     ,--R
238
 * 1RR00100    0     ,R   no offset
239
 * 1RRi0101    0     B,R
240
 * 1RRi0110    0     A,R
241
 * 1RRi1000    1     n,R n is signed 8 bit
242
 * 1RRi1001    2     n,R n is signed 16 bit
243
 * 1RRi1011    0     D,R
244
 * 1xxi1100    1     n,PC  n is signed 8 bit postbyte
245
 * 1xxi1101    2     n,PC  n is 16 bit postbytes
246
 *
247
 * RR
248
 * 00  X
249
 * 01  Y
250
 * 10  U
251
 * 11  S
252
 */
253
always @(*)
254
        begin
255
                eamem_addr = 16'hFEED; // for debug purposes
256
                casex (eapostbyte)
257
                        8'b0xx0xxxx: // 5 bit signed offset +
258
                                eamem_addr = ea_reg + { 12'h0, eapostbyte[3:0] };
259
                        8'b0xx1xxxx: // 5 bit signed offset -
260
                                eamem_addr = ea_reg + { 12'hfff, eapostbyte[3:0] };
261
                        8'b1xx_x_0000, // post increment, increment occurs at a later stage
262
                        8'b1xx_x_0001, // post increment, increment occurs at a later stage
263
                        8'b1xx_x_0100: // no offset
264
                                eamem_addr = ea_reg;
265
                        8'b1xx_x_0010, // pre decrement
266
                        8'b1xx_x_0011: // pre decrement
267
                                eamem_addr = ea_reg_post; // gets precalculated pre-decremented address
268
                        8'b1xx_x_0101: // B,R
269
                                eamem_addr = ea_reg + { {8{accb[7]}}, accb };
270
                        8'b1xx_x_0110: // A,R
271
                                eamem_addr = ea_reg + { {8{acca[7]}}, acca };
272
                        8'b1xx_x_1011: // D,R
273
                                eamem_addr = ea_reg + { acca, accb };
274
                        8'b1xx_x_1000: // n,R 8 bit offset
275
                                eamem_addr = ea_reg + { offset16[7] ? 8'hff:8'h0, offset16[7:0] }; // from postbyte1
276
                        8'b1xx_x_1001: // n,R // 16 bit offset
277
                                eamem_addr = ea_reg + offset16;
278
                        8'b1xx_x_1100: // n,PC
279
                                eamem_addr = pc + { offset16[7] ? 8'hff:8'h0, offset16[7:0] };
280
                        8'b1xx_x_1101: // n,PC
281
                                eamem_addr = pc + offset16;
282
                endcase
283
        end
284
 
285
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.