OpenCores
URL https://opencores.org/ocsvn/a-z80/a-z80/trunk

Subversion Repositories a-z80

[/] [a-z80/] [trunk/] [cpu/] [alu/] [test_alu.sv] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 gdevic
//==============================================================
2
// Test complete ALU block
3
//==============================================================
4
`timescale 100 ns/ 100 ns
5
 
6
module test_alu;
7
 
8
// ----------------- CLOCKS AND RESET -----------------
9
// Define one full T-clock cycle delay
10
`define T #2
11
bit clk = 1;
12
initial repeat (24) #1 clk = ~clk;
13
 
14
// ------------------------ BUS LOGIC ------------------------
15
// Bus control
16
logic alu_oe;               // ALU unit output enable to the outside bus
17
 
18
// Write to the ALU internal data buses
19
logic alu_op1_oe;           // Enable writing by the OP1 latch
20
logic alu_op2_oe;           // Enable writing by the OP2 latch
21
logic alu_res_oe;           // Enable writing by the ALU result latch
22
logic alu_shift_oe;         // Enable writing by the input shifter
23
logic alu_bs_oe;            // Enable writing by the input bit selector
24
// Our own test internal mux to select ALU bus writers
25
logic [2:0] bus_sel;        // Select internal bus writer:
26
 
27
typedef enum logic[2:0] {
28
    BUS_HIGHZ, BUS_OP1, BUS_OP2, BUS_RES, BUS_SHIFT, BUS_BS
29
} bus_t;
30
 
31
// Mux to select only one block to drive internal ALU bus
32
always_comb
33
begin
34
    alu_op1_oe = 0;
35
    alu_op2_oe = 0;
36
    alu_res_oe = 0;
37
    alu_shift_oe = 0;
38
    alu_bs_oe = 0;
39
    case (bus_sel)
40
        BUS_OP1     : alu_op1_oe = 1;
41
        BUS_OP2     : alu_op2_oe = 1;
42
        BUS_RES     : alu_res_oe = 1;
43
        BUS_SHIFT   : alu_shift_oe = 1;
44
        BUS_BS      : alu_bs_oe = 1;
45
    endcase
46
end
47
 
48
// ------------------------ INPUT ------------------------
49
// Input shifter control wires and output from the shifter
50
logic alu_shift_in;         // Carry-in into the shifter
51
logic alu_shift_right;      // Shift right
52
logic alu_shift_left;       // Shift left
53
wire alu_shift_db0;         // Output db[0] from the shifter for the shift logic
54
wire alu_shift_db7;         // Output db[7] from the shifter for the shift logic
55
 
56
// Input bit selector control wires
57
logic [2:0] bsel;           // Selects a bit to generate
58
 
59
// Operator latch 1 mux select
60
logic alu_op1_sel_bus;      // OP1 is read from the internal bus
61
logic alu_op1_sel_low;      // OP1 is read from the low nibble
62
logic alu_op1_sel_zero;     // OP1 is loaded with zero
63
 
64
// Operator 2 latch mux select
65
logic alu_op2_sel_bus;      // OP2 is read from the internal bus
66
logic alu_op2_sel_lq;       // OP2 is read from the L-Q gates (see schematic)
67
logic alu_op2_sel_zero;     // OP2 is loaded with zero
68
 
69
// ALU operator mux select
70
logic alu_sel_op2_neg;      // Selects complemented OP2
71
logic alu_sel_op2_high;     // Selects high OP2 nibble as opposed to low
72
 
73
// ALU Core operations
74
logic alu_core_cf_in;       // Carry input into the ALU core
75
logic alu_core_R;           // Operation control "R"
76
logic alu_core_S;           // Operation control "S"
77
logic alu_core_V;           // Operation control "V"
78
logic alu_op_low;           // Signal to compute and store the low nibble (see schematic)
79
wire alu_core_cf_out;       // Output carry bit from the ALU core
80
wire alu_vf_out;            // Output overflow flag from the ALU
81
 
82
// Zero-detect, parity calculation, flag preparation and DAA-preparation logic
83
logic alu_parity_in;        // Input parity bit from a previous nibble
84
wire alu_parity_out;        // Output parity on the result and a previous nibble
85
wire alu_zero;              // Output signal that the result is zero
86
wire alu_sf_out;            // Output signal containing the result sign bit
87
wire alu_yf_out;            // Output signal containing the result[5] bit which is YF
88
wire alu_xf_out;            // Output signal containing the result[3] bit which is XF
89
wire alu_low_gt_9;          // Output signal that the low nibble result > 9
90
wire alu_high_gt_9;         // Output signal that the high nibble result > 9
91
wire alu_high_eq_9;         // Output signal that the high nibble result == 9
92
 
93
// ------------------------ BUSSES ------------------------
94
// Bidirectional data bus, interface to the outside world
95
logic  [7:0] db_w;          // Drive it using this bus
96
wire [7:0] db;              // Read it using this bus
97
 
98
wire [3:0] test_db_low;     // Test point to probe internal low nibble bus
99
wire [3:0] test_db_high;    // Test point to probe internal high nibble bus
100
 
101
// ------------------------ FLAGS  ------------------------
102
reg cf;                     // Carry flag
103
reg pf;                     // Parity flag
104
reg hf;                     // Half-carry flag
105
 
106
// ----------------- TEST -------------------
107
initial begin
108
    // Init / reset
109
    db_w = 8'h00;
110
    bus_sel = BUS_HIGHZ;
111
 
112
    alu_shift_in = 0;
113
    alu_shift_right = 0;
114
    alu_shift_left = 0;
115
 
116
    bsel = 2'h0;
117
 
118
    alu_op1_sel_bus = 0;
119
    alu_op1_sel_low = 0;
120
    alu_op1_sel_zero = 0;
121
 
122
    alu_op2_sel_bus = 0;
123
    alu_op2_sel_lq = 0;
124
    alu_op2_sel_zero = 0;
125
 
126
    alu_sel_op2_neg = 0;
127
    alu_sel_op2_high = 0;
128
 
129
    alu_parity_in = 0;
130
    alu_core_cf_in = 0;
131
    alu_core_R = 0;
132
    alu_core_S = 0;
133
    alu_core_V = 0;
134
    alu_op_low = 0;
135
 
136
    cf = 0;
137
    hf = 0;
138
    pf = 0;
139
 
140
    //------------------------------------------------------------
141
    // Test loading to internal bus from the input shifter through the OP1 latch
142
    `T  db_w = 8'h24;                   // High: 0010  Low: 0100
143
        bus_sel = BUS_SHIFT;
144
        alu_shift_right = 1;            // Enable shift and shift *right*
145
        alu_shift_in = 1;               // shift in <- 1
146
        alu_op1_sel_bus = 1;            // Write into the OP1 latch
147
 
148
    `T  db_w = 'z;
149
        alu_op1_sel_bus = 0;
150
        alu_shift_in = 0;
151
        bus_sel = BUS_OP1;              // Read back OP1 latch
152
        alu_shift_right = 0;
153
        // Expected output on the external ALU bus : 1001 0010, 0x92
154
    `T  assert(db==8'h92);
155
        // Reset
156
        bus_sel = BUS_HIGHZ;
157
 
158
    //------------------------------------------------------------
159
    // Test loading to internal bus from the input bit selector through the OP2 latch
160
    `T  db_w = 'z;                      // Not using external bus to load, but the bit-select
161
        bsel = 2'h3;                    // Bit 3:  0000 1000
162
        bus_sel = BUS_BS;
163
        alu_op2_sel_bus = 1;            // Write into the OP2 latch
164
 
165
    `T  db_w = 'z;
166
        alu_op2_sel_bus = 0;
167
        alu_shift_in = 0;
168
        bus_sel = BUS_OP2;
169
        bsel = 2'h0;
170
        // Expected output on the external ALU bus : 0000 1000, 0x08
171
    `T  assert(db==8'h08);
172
        // Reset
173
    `T  bus_sel = BUS_HIGHZ;
174
 
175
    //------------------------------------------------------------
176
    // Test the full adding function, ADD
177
    `T  db_w = 8'h8C;                   // Operand 1:  8C
178
        bus_sel = BUS_SHIFT;            // Shifter writes to internal bus
179
        alu_op1_sel_bus = 1;            // Write into the OP1 latch
180
 
181
    `T  db_w = 8'h68;                   // Operand 1:  68
182
        alu_op_low = 1;                 // Perform the low nibble calculation
183
        alu_op1_sel_bus = 0;
184
        bus_sel = BUS_SHIFT;            // Shifter writes to internal bus
185
        alu_op2_sel_bus = 1;            // Write into the OP2 latch
186
        // Do a low nibble addition in this cycle
187
        alu_sel_op2_high = 0;           // ALU select low OP nibble
188
        alu_parity_in = 0;              // Reset parity of the nibble
189
        alu_core_cf_in = 0;             // CF in 0
190
        alu_core_R = 0;
191
        alu_core_S = 0;
192
        alu_core_V = 0;
193
        hf = alu_core_cf_out;           // Load the HF with the half-carry out
194
        pf = alu_parity_out;            // Load the PF with the parity of the nibble result
195
 
196
    `T  db_w = 'z;
197
        alu_op_low = 0;                 // Perform the high nibble calculation
198
        alu_op2_sel_bus = 0;
199
        alu_sel_op2_high = 1;           // ALU select high OP2 nibble
200
        alu_core_cf_in = 0;
201
        alu_core_cf_in = hf;            // Carry in the half-carry
202
        alu_parity_in = pf;             // Parity in the parity of the low result nibble
203
        bus_sel = BUS_RES;              // ALU result latch writes to the bus
204
        // Expected output on the external ALU bus : 8C + 68 = F4
205
    `T  assert(db==8'hF4);
206
        // Reset
207
        bus_sel = BUS_HIGHZ;
208
 
209
    `T  $display("End of test");
210
end
211
 
212
//--------------------------------------------------------------
213
// External bus logic
214
assign db = db_w;           // Drive 3-state bidirectional bus
215
always_comb                 // Output internal ALU bus only when our
216
begin                       // test is not driving it
217
    if (db_w==='z)
218
        alu_oe = 1;
219
    else
220
        alu_oe = 0;
221
end
222
 
223
//--------------------------------------------------------------
224
// Instantiate ALU block and assign identical nets and variables
225
//--------------------------------------------------------------
226
 
227
alu alu_inst( .* );
228
 
229
endmodule

powered by: WebSVN 2.1.0

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