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 2

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

powered by: WebSVN 2.1.0

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