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 4

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

powered by: WebSVN 2.1.0

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