1 |
2 |
MichaelA |
///////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// Copyright 2009-2012 by Michael A. Morris, dba M. A. Morris & Associates
|
4 |
|
|
//
|
5 |
|
|
// All rights reserved. The source code contained herein is publicly released
|
6 |
|
|
// under the terms and conditions of the GNU Lesser Public License. No part of
|
7 |
|
|
// this source code may be reproduced or transmitted in any form or by any
|
8 |
|
|
// means, electronic or mechanical, including photocopying, recording, or any
|
9 |
|
|
// information storage and retrieval system in violation of the license under
|
10 |
|
|
// which the source code is released.
|
11 |
|
|
//
|
12 |
|
|
// The source code contained herein is free; it may be redistributed and/or
|
13 |
|
|
// modified in accordance with the terms of the GNU Lesser General Public
|
14 |
|
|
// License as published by the Free Software Foundation; either version 2.1 of
|
15 |
|
|
// the GNU Lesser General Public License, or any later version.
|
16 |
|
|
//
|
17 |
|
|
// The source code contained herein is freely released WITHOUT ANY WARRANTY;
|
18 |
|
|
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
19 |
|
|
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
|
20 |
|
|
// more details.)
|
21 |
|
|
//
|
22 |
|
|
// A copy of the GNU Lesser General Public License should have been received
|
23 |
|
|
// along with the source code contained herein; if not, a copy can be obtained
|
24 |
|
|
// by writing to:
|
25 |
|
|
//
|
26 |
|
|
// Free Software Foundation, Inc.
|
27 |
|
|
// 51 Franklin Street, Fifth Floor
|
28 |
|
|
// Boston, MA 02110-1301 USA
|
29 |
|
|
//
|
30 |
|
|
// Further, no use of this source code is permitted in any form or means
|
31 |
|
|
// without inclusion of this banner prominently in any derived works.
|
32 |
|
|
//
|
33 |
|
|
// Michael A. Morris
|
34 |
|
|
// Huntsville, AL
|
35 |
|
|
//
|
36 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
37 |
|
|
|
38 |
|
|
`timescale 1ns / 1ps
|
39 |
|
|
|
40 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
41 |
|
|
// Company: M. A. Morris & Associates
|
42 |
|
|
// Engineer: Michael A. Morris
|
43 |
|
|
//
|
44 |
|
|
// Create Date: 12/06/2009
|
45 |
|
|
// Design Name: WDC W65C02 Microprocessor Re-Implementation
|
46 |
|
|
// Module Name: M65C02_BCD
|
47 |
|
|
// Project Name: C:\XProjects\ISE10.1i\MAM6502
|
48 |
|
|
// Target Devices: Generic SRAM-based FPGA
|
49 |
|
|
// Tool versions: Xilinx ISE10.1i SP3
|
50 |
|
|
//
|
51 |
|
|
// Description:
|
52 |
|
|
//
|
53 |
|
|
// Verilog Test Fixture created by ISE for module: M65C02_BCD.v
|
54 |
|
|
//
|
55 |
|
|
// Revision:
|
56 |
|
|
//
|
57 |
|
|
// 0.01 09L06 MAM Initial coding
|
58 |
|
|
//
|
59 |
|
|
// 1.00 12D28 MAM Modified to support release version of the BCD
|
60 |
|
|
// adder module, which is separate from the binary
|
61 |
|
|
// adder module.
|
62 |
|
|
//
|
63 |
|
|
// Additional Comments:
|
64 |
|
|
//
|
65 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
66 |
|
|
|
67 |
|
|
module tb_W65C02_BCD;
|
68 |
|
|
|
69 |
|
|
// System Interface
|
70 |
|
|
|
71 |
|
|
reg Rst;
|
72 |
|
|
reg Clk;
|
73 |
|
|
|
74 |
|
|
// Inputs
|
75 |
|
|
|
76 |
|
|
reg En;
|
77 |
|
|
reg Sub;
|
78 |
|
|
|
79 |
|
|
reg [7:0] A;
|
80 |
|
|
reg [7:0] B;
|
81 |
|
|
reg Ci;
|
82 |
|
|
|
83 |
|
|
// Outputs
|
84 |
|
|
|
85 |
|
|
wire [7:0] Sum;
|
86 |
|
|
wire Co;
|
87 |
|
|
wire OV;
|
88 |
|
|
wire Valid;
|
89 |
|
|
|
90 |
|
|
// Simulation Variables
|
91 |
|
|
|
92 |
|
|
integer i, j, k;
|
93 |
|
|
|
94 |
|
|
reg [4:0] LSN, MSN;
|
95 |
|
|
reg C3, C7;
|
96 |
|
|
reg [7:0] ALU;
|
97 |
|
|
reg N, V, Z, C;
|
98 |
|
|
|
99 |
|
|
// Instantiate the Unit Under Test (UUT)
|
100 |
|
|
|
101 |
|
|
M65C02_BCD uut (
|
102 |
|
|
.Rst(Rst),
|
103 |
|
|
.Clk(Clk),
|
104 |
|
|
.En(En),
|
105 |
|
|
|
106 |
|
|
.Op(Sub),
|
107 |
|
|
|
108 |
|
|
.A(A),
|
109 |
|
|
.B(B),
|
110 |
|
|
.Ci(Ci),
|
111 |
|
|
.Out({Co, Sum}),
|
112 |
|
|
.OV(OV),
|
113 |
|
|
.Valid(Valid)
|
114 |
|
|
);
|
115 |
|
|
|
116 |
|
|
initial begin
|
117 |
|
|
Rst = 1;
|
118 |
|
|
Clk = 1;
|
119 |
|
|
|
120 |
|
|
En = 0;
|
121 |
|
|
Sub = 0;
|
122 |
|
|
A = 0;
|
123 |
|
|
B = 0;
|
124 |
|
|
Ci = 0;
|
125 |
|
|
|
126 |
|
|
i = 0; j = 0; k = 0;
|
127 |
|
|
LSN = 0; MSN = 0; C3 = 0; C7 = 0; ALU = 0; {N,V,Z,C} = 0;
|
128 |
|
|
|
129 |
|
|
// Wait 100 ns for global reset to finish
|
130 |
|
|
|
131 |
|
|
#101 Rst = 0;
|
132 |
|
|
|
133 |
|
|
$display("Begin Adder Tests");
|
134 |
|
|
|
135 |
|
|
// BCD Tests
|
136 |
|
|
|
137 |
|
|
$display("Start Decimal Mode Addition Test");
|
138 |
|
|
|
139 |
|
|
Sub = 0; // ADC Test
|
140 |
|
|
|
141 |
|
|
for(i = 0; i < 100; i = i + 1) begin
|
142 |
|
|
k = (i / 10);
|
143 |
|
|
A = (k * 16) + (i - (k * 10));
|
144 |
|
|
for(j = 0; j < 100; j = j + 1) begin
|
145 |
|
|
k = (j / 10);
|
146 |
|
|
B = (k * 16) + (j - (k * 10));
|
147 |
|
|
Ci = 0;
|
148 |
|
|
En = 1;
|
149 |
|
|
@(posedge Clk) #0.9 En = 0;
|
150 |
|
|
@(posedge Valid) #0.1;
|
151 |
|
|
if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
152 |
|
|
$display("Error: Incorrect Result");
|
153 |
|
|
$display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci);
|
154 |
|
|
$display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
155 |
|
|
$display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
156 |
|
|
$display("End Decimal Mode Addition Test: Fail");
|
157 |
|
|
$stop;
|
158 |
|
|
end
|
159 |
|
|
@(posedge Clk) #1;
|
160 |
|
|
Ci = 1;
|
161 |
|
|
En = 1;
|
162 |
|
|
@(posedge Clk) #0.9 En = 0;
|
163 |
|
|
@(posedge Valid) #0.1;
|
164 |
|
|
if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
165 |
|
|
$display("Error: Incorrect Result");
|
166 |
|
|
$display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci);
|
167 |
|
|
$display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
168 |
|
|
$display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
169 |
|
|
$display("End Decimal Mode Addition Test: Fail");
|
170 |
|
|
$stop;
|
171 |
|
|
end
|
172 |
|
|
@(posedge Clk) #1;
|
173 |
|
|
end
|
174 |
|
|
end
|
175 |
|
|
|
176 |
|
|
$display("End Decimal Mode Addition Test: Pass");
|
177 |
|
|
|
178 |
|
|
// SBC Test
|
179 |
|
|
|
180 |
|
|
$display("Start Decimal Mode Subtraction Test");
|
181 |
|
|
|
182 |
|
|
Sub = 1; // SBC Test
|
183 |
|
|
|
184 |
|
|
for(i = 0; i < 100; i = i + 1) begin
|
185 |
|
|
k = (i / 10);
|
186 |
|
|
A = (k * 16) + (i - (k * 10));
|
187 |
|
|
for(j = 0; j < 100; j = j + 1) begin
|
188 |
|
|
k = (j / 10);
|
189 |
|
|
B = ~((k * 16) + (j - (k * 10)));
|
190 |
|
|
Ci = 1;
|
191 |
|
|
En = 1;
|
192 |
|
|
@(posedge Clk) #0.9 En = 0;
|
193 |
|
|
@(posedge Valid) #0.1;
|
194 |
|
|
if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
195 |
|
|
$display("Error: Incorrect Result");
|
196 |
|
|
$display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci);
|
197 |
|
|
$display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
198 |
|
|
$display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
199 |
|
|
$display("End Decimal Mode Subtraction Test: Fail");
|
200 |
|
|
$stop;
|
201 |
|
|
end
|
202 |
|
|
@(posedge Clk) #1;
|
203 |
|
|
Ci = 0;
|
204 |
|
|
En = 1;
|
205 |
|
|
@(posedge Clk) #0.9 En = 0;
|
206 |
|
|
@(posedge Valid) #0.1;
|
207 |
|
|
if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
208 |
|
|
$display("Error: Incorrect Result");
|
209 |
|
|
$display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci);
|
210 |
|
|
$display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
211 |
|
|
$display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
212 |
|
|
$display("End Decimal Mode Subtraction Test: Fail");
|
213 |
|
|
$stop;
|
214 |
|
|
end
|
215 |
|
|
@(posedge Clk) #1;
|
216 |
|
|
end
|
217 |
|
|
end
|
218 |
|
|
|
219 |
|
|
$display("End Decimal Mode Subtraction Test: Pass");
|
220 |
|
|
|
221 |
|
|
// // Binary Tests
|
222 |
|
|
//
|
223 |
|
|
// $display("Start Binary Mode Addition Test");
|
224 |
|
|
//
|
225 |
|
|
// En = 0; Op = 0; // ADC Test
|
226 |
|
|
//
|
227 |
|
|
// for(i = 0; i < 256; i = i + 1) begin
|
228 |
|
|
// A = i;
|
229 |
|
|
// for(j = 0; j < 256; j = j + 1) begin
|
230 |
|
|
// B = j;
|
231 |
|
|
// Ci = 0;
|
232 |
|
|
// #5;
|
233 |
|
|
// if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
234 |
|
|
// $display("Error: Incorrect Result");
|
235 |
|
|
// $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci);
|
236 |
|
|
// $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
237 |
|
|
// $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
238 |
|
|
// $display("End Binary Mode Addition Test: Fail");
|
239 |
|
|
// $stop;
|
240 |
|
|
// end
|
241 |
|
|
// #5;
|
242 |
|
|
// Ci = 1;
|
243 |
|
|
// #5;
|
244 |
|
|
// if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
245 |
|
|
// $display("Error: Incorrect Result");
|
246 |
|
|
// $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci);
|
247 |
|
|
// $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
248 |
|
|
// $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
249 |
|
|
// $display("End Decimal Mode Addition Test: Fail");
|
250 |
|
|
// $stop;
|
251 |
|
|
// end
|
252 |
|
|
// #5;
|
253 |
|
|
// end
|
254 |
|
|
// end
|
255 |
|
|
//
|
256 |
|
|
// $display("End Binary Mode Addition Test: Pass");
|
257 |
|
|
//
|
258 |
|
|
// // Binary Mode
|
259 |
|
|
//
|
260 |
|
|
// $display("Start Binary Mode Subtraction Test");
|
261 |
|
|
//
|
262 |
|
|
// En = 0; Op = 1; // SBC Test
|
263 |
|
|
//
|
264 |
|
|
// for(i = 0; i < 256; i = i + 1) begin
|
265 |
|
|
// A = i;
|
266 |
|
|
// for(j = 0; j < 256; j = j + 1) begin
|
267 |
|
|
// B = ~j;
|
268 |
|
|
// Ci = 1;
|
269 |
|
|
// #5;
|
270 |
|
|
// if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
271 |
|
|
// $display("Error: Incorrect Result");
|
272 |
|
|
// $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci);
|
273 |
|
|
// $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
274 |
|
|
// $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
275 |
|
|
// $display("End Binary Mode Subtraction Test: Fail");
|
276 |
|
|
// $stop;
|
277 |
|
|
// end
|
278 |
|
|
// #5;
|
279 |
|
|
// Ci = 0;
|
280 |
|
|
// #5;
|
281 |
|
|
// if((Sum != ALU) || (Co != C) || (OV != V)) begin
|
282 |
|
|
// $display("Error: Incorrect Result");
|
283 |
|
|
// $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci);
|
284 |
|
|
// $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU);
|
285 |
|
|
// $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum);
|
286 |
|
|
// $display("End Decimal Mode Subtraction Test: Fail");
|
287 |
|
|
// $stop;
|
288 |
|
|
// end
|
289 |
|
|
// #5;
|
290 |
|
|
// end
|
291 |
|
|
// end
|
292 |
|
|
//
|
293 |
|
|
// $display("End Binary Mode Subtraction Test: Pass");
|
294 |
|
|
//
|
295 |
|
|
// $display("End Adder Tests: Pass");
|
296 |
|
|
|
297 |
|
|
$stop;
|
298 |
|
|
|
299 |
|
|
end
|
300 |
|
|
|
301 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
302 |
|
|
//
|
303 |
|
|
// System Clk
|
304 |
|
|
|
305 |
|
|
always #5 Clk = ~Clk;
|
306 |
|
|
|
307 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
308 |
|
|
//
|
309 |
|
|
// BCD Mode Adder Model
|
310 |
|
|
//
|
311 |
|
|
|
312 |
|
|
always @(*)
|
313 |
|
|
begin
|
314 |
|
|
// if(D) begin
|
315 |
|
|
if(Sub) begin
|
316 |
|
|
LSN[4:0] <= {1'b0, A[3:0]} + {1'b0, B[3:0]} + {4'b0, Ci};
|
317 |
|
|
C3 <= LSN[4] & ~(LSN[3] & (LSN[2] | LSN[1]));
|
318 |
|
|
ALU[3:0] <= ((C3) ? (LSN[3:0] + 0) : (LSN[3:0] + 10));
|
319 |
|
|
|
320 |
|
|
MSN[4:0] <= {1'b0, A[7:4]} + {1'b0, B[7:4]} + {4'b0, C3};
|
321 |
|
|
C7 <= MSN[4] & ~(MSN[3] & (MSN[2] | MSN[1]));
|
322 |
|
|
ALU[7:4] <= ((C7) ? (MSN[3:0] + 0) : (MSN[3:0] + 10));
|
323 |
|
|
end else begin
|
324 |
|
|
LSN[4:0] <= {1'b0, A[3:0]} + {1'b0, B[3:0]} + {4'b0, Ci};
|
325 |
|
|
C3 <= LSN[4] | (LSN[3] & (LSN[2] | LSN[1]));
|
326 |
|
|
ALU[3:0] <= ((C3) ? (LSN[3:0] + 6) : (LSN[3:0] + 0));
|
327 |
|
|
|
328 |
|
|
MSN[4:0] <= {1'b0, A[7:4]} + {1'b0, B[7:4]} + {4'b0, C3};
|
329 |
|
|
C7 <= MSN[4] | (MSN[3] & (MSN[2] | MSN[1]));
|
330 |
|
|
ALU[7:4] <= ((C7) ? (MSN[3:0] + 6) : (MSN[3:0] + 0));
|
331 |
|
|
end
|
332 |
|
|
|
333 |
|
|
N <= ALU[7]; V <= ((Sub) ? ~C7 : C7); Z <= ~|ALU; C <= C7;
|
334 |
|
|
// end else begin
|
335 |
|
|
// LSN[4:0] <= {1'b0, A[3:0]} + {1'b0, B[3:0]} + {4'b0, Ci};
|
336 |
|
|
// C3 <= LSN[4];
|
337 |
|
|
// ALU[3:0] <= LSN[3:0];
|
338 |
|
|
//
|
339 |
|
|
// MSN[3:0] <= {1'b0, A[6:4]} + {1'b0, B[6:4]} + {4'b0, C3};
|
340 |
|
|
// MSN[4] <= (MSN[3] & (A[7] ^ B[7]) | (A[7] & B[7]));
|
341 |
|
|
// C7 <= MSN[4];
|
342 |
|
|
// ALU[7:4] <= {A[7] ^ B[7] ^ MSN[3], MSN[2:0]};
|
343 |
|
|
//
|
344 |
|
|
// N <= ALU[7]; V <= (MSN[4] ^ MSN[3]); Z <= ~|ALU; C <= C7;
|
345 |
|
|
// end
|
346 |
|
|
end
|
347 |
|
|
|
348 |
|
|
endmodule
|
349 |
|
|
|