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 5

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
        input wire [15:0] data_w,
25
        input wire [15:0] new_pc,
26
        input wire [7:0] CCR_in,
27
        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
        output reg [15:0] eamem_addr,
34
        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
reg [15:0] ea_reg, ea_reg_post;
54
 
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
// left path output, always 16 bits
60
always @(*)
61
        begin
62
                case (path_left_addr)
63 5 ale500
                        `RN_ACCA:       path_left_data = { 8'hff, ACCA };
64
                        `RN_ACCB:       path_left_data = { 8'hff, ACCB };
65 2 ale500
                        `RN_ACCD:       path_left_data = `ACCD;
66
                        `RN_IX:         path_left_data = IX;
67
                        `RN_IY:         path_left_data = IY;
68
                        `RN_U:          path_left_data = SU;
69
                        `RN_S:          path_left_data = SS;
70
                        `RN_PC:         path_left_data = PC;
71 5 ale500
                        `RN_DP:         path_left_data = { DP, DP };
72
                        `RN_CC:         path_left_data = { `CCR, `CCR };
73 2 ale500
                        default:
74 5 ale500
                                path_left_data = 16'hFFFF;
75 2 ale500
                endcase
76
        end
77
 
78
// right path output, always 16 bits
79
always @(*)
80
        begin
81
                case (path_right_addr)
82 5 ale500
                        `RN_ACCA:       path_right_data = { 8'hff, ACCA };
83
                        `RN_ACCB:       path_right_data = { 8'hff, ACCB };
84
                        `RN_ACCD:       path_right_data = `ACCD;
85
                        `RN_IX:         path_right_data = IX;
86
                        `RN_IY:         path_right_data = IY;
87
                        `RN_U:          path_right_data = SU;
88
                        `RN_S:          path_right_data = SS;
89
                        `RN_DP:         path_right_data = { DP, DP };
90
                        `RN_CC:         path_right_data = { `CCR, `CCR };
91 2 ale500
                        default:
92 5 ale500
                                path_right_data = 16'hFFFF;
93
                endcase
94 2 ale500
        end
95
 
96
always @(*)
97
        begin
98
                case (eapostbyte[6:5])
99
                        2'b00: ea_reg = IX;
100
                        2'b01: ea_reg = IY;
101
                        2'b10: ea_reg = SU;
102
                        2'b11: ea_reg = SS;
103
                endcase
104
        end
105
// pre-decrement/postincrement
106
always @(*)
107
        begin
108
                ea_reg_post = ea_reg;
109
                casex (eapostbyte)
110
                        8'b1xxx0000: ea_reg_post = ea_reg + 16'h1;
111
                        8'b1xxx0001: ea_reg_post = ea_reg + 16'h2;
112
                        8'b1xxx0010: ea_reg_post = ea_reg - 16'h1;
113
                        8'b1xxx0011: ea_reg_post = ea_reg - 16'h2;
114
                        //default: ea_reg_post = ea_reg;
115
                endcase
116
        end
117
 
118
/* EA calculation
119
 * postbyte  bytes  assembler
120
 *
121
 * 0RRnnnnn    0     n,R  n is 5 bits signed
122
 * 1RRi0000    0     ,R+
123
 * 1RRi0001    0     ,R++
124
 * 1RRi0010    0     ,-R
125
 * 1RRi0011    0     ,--R
126
 * 1RR00100    0     ,R   no offset
127
 * 1RRi0101    0     B,R
128
 * 1RRi0110    0     A,R
129
 * 1RRi1000    1     n,R n is signed 8 bit
130
 * 1RRi1001    2     n,R n is signed 16 bit
131
 * 1RRi1011    0     D,R
132
 * 1xxi1100    1     n,PC  n is signed 8 bit postbyte
133
 * 1xxi1101    2     n,PC  n is 16 bit postbytes
134
 *
135
 * RR
136
 * 00  X
137
 * 01  Y
138
 * 10  U
139
 * 11  S
140
 */
141
always @(*)
142
        begin
143
                eamem_addr = 16'hFEED; // for debug purposes
144
                casex (eapostbyte)
145
                        8'b0xx0xxxx: // 5 bit signed offset +
146
                                eamem_addr = ea_reg + { 12'h0, eapostbyte[3:0] };
147
                        8'b0xx1xxxx: // 5 bit signed offset -
148
                                eamem_addr = ea_reg + { 12'hfff, eapostbyte[3:0] };
149
                        8'b1xx_x_0000, // post increment, increment occurs at a later stage
150
                        8'b1xx_x_0001, // post increment, increment occurs at a later stage
151
                        8'b1xx_x_0100: // no offset
152
                                eamem_addr = ea_reg;
153
                        8'b1xx_x_0010, // pre decrement
154
                        8'b1xx_x_0011: // pre decrement
155
                                eamem_addr = ea_reg_post; // gets precalculated pre-decremented address
156
                        8'b1xx_x_0101: // B,R
157
                                eamem_addr = ea_reg + { {8{ACCB[7]}}, ACCB };
158
                        8'b1xx_x_0110: // A,R
159
                                eamem_addr = ea_reg + { {8{ACCA[7]}}, ACCA };
160
                        8'b1xx_x_1011: // D,R
161
                                eamem_addr = ea_reg + `ACCD;
162
                        8'b1xx_x_1000: // n,R 8 bit offset
163
                                eamem_addr = ea_reg + { offset16[7] ? 8'hff:8'h0, offset16[7:0] }; // from postbyte1
164
                        8'b1xx_x_1001: // n,R // 16 bit offset
165
                                eamem_addr = ea_reg + offset16;
166
                        8'b1xx_x_1100: // n,PC
167
                                eamem_addr = PC + { offset16[7] ? 8'hff:8'h0, offset16[7:0] };
168
                        8'b1xx_x_1101: // n,PC
169
                                eamem_addr = PC + offset16;
170
                endcase
171
        end
172
 
173 5 ale500
wire [15:0] left;
174
 
175
assign left = (write_tfr | write_exg) ? path_left_data:data_w;
176
 
177
wire [15:0] new_su, old_su;
178
 
179
assign old_su = (use_s) ? SS:SU;
180
assign new_su = (inc_su) ? old_su + 16'h1:(dec_su) ? old_su - 16'h1:old_su;
181
 
182 2 ale500
always @(posedge clk_in)
183
        begin
184 5 ale500
                if (write_exg)
185
                        case (exg_dest_r)
186
                                0: `ACCD <= path_right_data;
187
                                1: IX <= path_right_data;
188
                                2: IY <= path_right_data;
189
                                3: SU <= path_right_data;
190
                                4: SS <= path_right_data;
191
                                5: PC <= path_right_data;
192
                                8: ACCA <= path_right_data[7:0];
193
                                9: ACCB <= path_right_data[7:0];
194
                                10: `CCR <= path_right_data[7:0];
195
                                11: DP <= path_right_data[7:0];
196
                        endcase
197
                if (write_tfr | write_exg | write_reg)
198 2 ale500
                        case (write_reg_addr)
199 5 ale500
                                0: `ACCD <= left;
200
                                1: IX <= left;
201
                                2: IY <= left;
202
                                3: SU <= left;
203
                                4: SS <= left;
204
                                5: PC <= left;
205
                                8: ACCA <= left[7:0];
206
                                9: ACCB <= left[7:0];
207
                                10: `CCR <= left[7:0];
208
                                11: DP <= left[7:0];
209 2 ale500
                        endcase
210
                if (write_post) // write back predecrement/postincremented values
211
                        begin
212
                                case (eapostbyte[6:5])
213
                                        2'b00: IX <= ea_reg_post;
214
                                        2'b01: IY <= ea_reg_post;
215
                                        2'b10: SU <= ea_reg_post;
216
                                        2'b11: SS <= ea_reg_post;
217
                                endcase
218
                        end
219
                if (write_flags)
220
                        begin
221
                                `CCR <= CCR_in;
222
                        end
223 5 ale500
                if (set_e) eflag <= 1;
224
                if (clear_e) eflag <= 0;
225 2 ale500
                if (write_pc) PC <= new_pc;
226
                if (inc_pc) PC <= PC + 16'h1;
227 5 ale500
 
228
                if (inc_su | dec_su)
229
                        begin
230
                                if (use_s) SS <= new_su;
231
                                else SU <= new_su;
232
                        end
233
/*
234 2 ale500
                if (inc_su)
235
                        if (use_s) SS <= SS + 16'h1;
236
                        else SU <= SU + 16'h1;
237
                if (dec_su)
238
                        if (use_s) SS <= SS - 16'h1;
239
                        else SU <= SU - 16'h1;
240 5 ale500
*/
241 2 ale500
        end
242
 
243
`ifdef SIMULATION
244
initial
245
        begin
246
                PC = 16'hfffe;
247
                DP = 8'h00;
248
                IX = 16'h0;
249
                `CCR = 0;
250
                IY = 16'hA55A;
251
                SS = 16'h0f00;
252
                SU = 16'h0e00;
253
        end
254
`endif
255
endmodule

powered by: WebSVN 2.1.0

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