OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [in_out_ports.sv] - Blame information for rev 22

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 Agner
//////////////////////////////////////////////////////////////////////////////////
2
// Engineer: Agner Fog
3
//
4
// Create Date:    2020-11-16
5
// Last modified:  2021-08-03
6
// Module Name:    in_out_ports
7
// Project Name:   ForwardCom soft core
8
// Target Devices: Artix 7
9
// Tool Versions:  Vivado v. 2020.1
10
// License:        CERN-OHL-W v. 2 or later
11
// Description:    Input and output ports, as well as reading and writing of special
12
// registers, including capabilities registers and performance counter registers
13
//////////////////////////////////////////////////////////////////////////////////
14
 
15
/* Input and output ports:
16
All input and output bits beyond the specified operand size are set to zero.
17
The port address can have up to 64 bits regardless of the specified operand size.
18
 
19
The following input and output ports are currently defined:
20
-----------------------------------------------------------
21
 
22
RS232 serial input and output.
23
Transmission settings: 8 data bits, one stop bit, no parity, no flow control.
24
The BAUD rate is currently defined in the file defines.vh
25
 
26
Input port 8. Serial input:
27
Read one byte from RS232 serial input. Non-blocking
28
The following value is returned:
29
bit 0-7: Received data (zero if input buffer empty)
30
bit   8: Data valid. Unreliable!
31
bit   9: More data ready: The input buffer contains at least one more byte ready to read
32
bit  12: Buffer overflow error. Data has been lost due to input buffer overflow
33
bit  13: Frame error. Error detected in start bit or stop bit. May be due to noise or wrong BAUD rate
34
 
35
Input port 9. Serial input status:
36
bit 0-15: Number of bytes currently in input buffer
37
bit   16: Buffer overflow error. Data has been lost due to input buffer overflow
38
bit   17: Frame error. Error detected in start bit or stop bit. May be due to noise or wrong BAUD rate
39
 
40
Output port 9. Serial input control:
41
bit    0: Clear buffer. Delete all data currently in the input buffer, and clear error flags
42
bit    1: Clear error flags but keep data.
43
          The error bits remain high after an error condition until reset by this or by system reset
44
 
45
Output port 10. Serial output:
46
Write one byte to RS232 serial output.
47
bit 0-7: Data to write
48
Other bits are reserved.
49
 
50
Input port 11. Serial output status:
51
bit 0-15: Number of bytes currently in output buffer
52
bit   16: Buffer overflow error. Data has been lost due to output buffer overflow
53
bit   18: Ready. The output buffer has enough space to receive at least one more byte
54
 
55
Output port 11. Serial output control:
56
bit    0: Clear buffer. Delete all data currently in the output buffer, and clear error flags
57
bit    1: Clear error flags but keep data.
58
The error bits remain high after an error condition until reset by this or by system reset
59
 
60
 
61
The following special registers are currently defined:
62
-----------------------------------------------------------
63
Capabilities registers 0, 1, 4, 5
64
Performance counter registers 1 - 5, and 16
65
 
66
*/
67
 
68
`include "defines.vh"
69
 
70
module in_out_ports (
71
    input clock,                            // system clock (100 MHz)
72
    input clock_enable,                     // clock enable. Used when single-stepping
73
    input reset,                            // system reset
74
    input valid_in,                         // data from previous stage ready
75
    input stall_in,                         // pipeline is stalled
76
    input [31:0] instruction_in,            // current instruction, up to 3 words long. Only first word used here
77
    input [`TAG_WIDTH-1:0] tag_val_in,      // instruction tag value
78
    input [1:0]  category_in,               // 00: multiformat, 01: single format, 10: jump
79
    input [1:0]  result_type_in,            // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
80
    input        mask_alternative_in,       // mask register used for alternative purposes
81
    input        vector_in,                 // this is a vector instruction
82
    input [6:0]  opx_in,                    // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
83
    input [5:0]  opj_in,                    // operation ID for conditional jump instructions
84
    input [2:0]  ot_in,                     // operand type
85
    input        regmask_used_in,           // mask register is used
86
    input uart_bit_in,                      // serial input
87
    input uart_rts_in,                      // ready to send input (not used)
88
 
89
    // monitor result buses:
90
    input write_en1,                        // a result is written to writeport1
91
    input [`TAG_WIDTH-1:0] write_tag1_in,   // tag of result inwriteport1
92
    input [`RB1:0] writeport1_in,           // result bus 1
93
    input write_en2,                        // a result is written to writeport2
94
    input [`TAG_WIDTH-1:0] write_tag2_in,   // tag of result inwriteport2
95
    input [`RB1:0] writeport2_in,           // result bus 2
96
    input [`TAG_WIDTH-1:0] predict_tag1_in, // result tag value on writeport1 in next clock cycle
97
    input [`TAG_WIDTH-1:0] predict_tag2_in, // result tag value on writeport2 in next clock cycle
98
 
99
    // Register values sampled from result bus in previous stages
100
    input [`RB:0] operand1_in,              // first register operand RD or RU
101
    input [`RB:0] operand2_in,              // second register operand RS
102
    input [`RB:0] operand3_in,              // last register operand RT
103
    input [`MASKSZ:0] regmask_val_in,       // mask register
104
    input         opr1_used_in,             // operand1_in is needed
105
 
106
    // signals used for performance monitoring and error detection
107
    input instruction_valid_in,             // instruction is valid but possibly going to a different exe unit
108
    input fast_jump_in,                     // a jump is bypassing the pipeline
109
    input [`N_ERROR_TYPES-1:0] errors_detect_in, // one bit for each type of error detected
110
    // instruction pointer at position of error
111
    input [`CODE_ADDR_WIDTH-1:0] fetch_instruction_pointer,
112
    input [`CODE_ADDR_WIDTH-1:0] dataread_instruction_pointer,
113
    input dataread_valid,                   // used when reconstructing alu_instruction_pointer
114
    input call_stack_overflow,              // used for differentiating errors_detect_in[1]
115
    input clear_error_in,                   // debugger clear error
116
 
117
    // outputs
118
    output reg valid_out,                   // for debug display: in_out is active
119
    output reg register_write_out,
120
    output reg [5:0] register_a_out,        // register to write
121
    output reg [`RB1:0] result_out,         // value to write to register
122
    output reg [`TAG_WIDTH-1:0] tag_val_out,// instruction tag value
123
    output reg nojump_out,                  // serializing instruction finished
124
    output reg stall_out,                   // alu is waiting for an operand or not ready to receive a new instruction
125
    output reg stall_next_out,              // alu will be waiting in next clock cycle
126
    output reg error_out,                   // unknown instruction
127
    output reg error_parm_out,              // wrong parameter for instruction
128
    output reg uart_bit_out,                // serial output
129
    output reg uart_cts_out,                // serial clear to send
130
    output reg [`N_ERROR_TYPES-1:0] capab_disable_errors, // capab2 register: disable errors
131
    output reg [3:0] first_error,           // error type for first error
132
    output reg [`CODE_ADDR_WIDTH-1:0] first_error_address, // code address of first error
133
    output reg [31:0] debug_out             // debug information
134
);
135
 
136
 
137
logic [`RB1:0] operand1;                    // first register operand RD or RU. bit `RB is 1 if invalid
138
logic [`RB1:0] operand2;                    // second register operand RS. bit `RB is 1 if invalid
139
logic [`RB1:0] operand3;                    // last register operand RT. bit `RB is 1 if invalid
140
logic [`MASKSZ:0] regmask_val;              // mask register
141
logic [1:0]  otout;                         // operand type for output
142
logic [`RB1:0] result;                      // result for output
143
logic [6:0]  opx;                           // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
144
logic [4:0] rs;                             // RS field in instruction
145
logic [4:0] rd;                             // RD field in instruction
146
logic stall;                                // waiting for operands
147
logic stall_next;                           // will be waiting for operands in next clock cycle
148
logic error;                                // unknown instruction
149
logic error_parm;                           // wrong parameter for instruction
150
 
151
logic [`RB1:0] port_address;                // address of input or output port
152
 
153
// submodules signals
154
reg UART_RX_receive_complete;
155
reg UART_RX_error;
156
reg [7:0] UART_RX_byte_out;
157
reg UART_TX_active;
158
reg UART_TX_tx_out;
159
reg UART_TX_done;
160
 
161
reg [7:0] fifo_buffer_input_byte;           // serial byte output prefetched
162
reg fifo_buffer_input_ready;                // the buffer contains at least one byte
163
reg fifo_buffer_input_overflow;             // attempt to write to full buffer
164
reg fifo_buffer_input_underflow;            // attempt to read from empty buffer
165
reg [`IN_BUFFER_SIZE_LOG2-1:0] fifo_buffer_input_num; // number of bytes currently in input buffer
166
 
167
reg [7:0] serial_output_byte_in;            // serial byte output
168
reg [7:0] fifo_buffer_output_byte;          // serial byte output prefetched from buffer
169
reg fifo_buffer_output_ready;               // the buffer contains at least one byte
170
reg fifo_buffer_output_overflow;            // attempt to write to full buffer
171
reg fifo_buffer_output_underflow;           // attempt to read from empty buffer
172
reg [`OUT_BUFFER_SIZE_LOG2-1:0] fifo_buffer_output_num; // number of bytes currently in output buffer
173
 
174
logic fifo_buffer_input_read_next;
175
logic fifo_buffer_input_reset;
176
logic fifo_buffer_input_reset_error;
177
logic fifo_buffer_output_write;
178
logic fifo_buffer_output_reset;
179
logic fifo_buffer_output_reset_error;
180
logic mask_off;
181
 
182
// temporary debug info
183
logic [31:0] debug_bits;
184
 
185
// performance counters
186
reg [`RB1:0] cpu_clock_cycles;              // count CPU clock cycles
187
reg [`RB1:0] num_instructions;              // count instructions
188
reg [`RB1:0] num_instructions_2size;        // count double size instructions
189
reg [`RB1:0] num_instructions_3size;        // count triple size instructions
190
reg [`RB1:0] num_instructions_gp;           // count instructions with g.p. registers
191
reg [`RB1:0] num_instructions_gp_mask0;     // count instructions with g.p. registers and mask = 0
192
reg [`RB1:0] num_instructions_vector;       // count instructions with vector registers
193
reg [`RB1:0] num_jump_call_return;          // count control transfer instructions
194
reg [`RB1:0] num_jump_call_direct;          // count direct unconditional jumps and calls
195
reg [`RB1:0] num_jump_call_indirect;        // count indirect jumps and calls
196
reg [`RB1:0] num_jump_conditional;          // count conditional jumps
197
reg [`RB1:0] num_unknown_instruction;       // count unknown instruction
198
reg [`RB1:0] num_wrong_operands;            // count wrong operands for instructions
199
reg [`RB1:0] num_array_overflow;            // count array index out of range
200
reg [`RB1:0] num_read_violation;            // count memory read access violation
201
reg [`RB1:0] num_write_violation;           // count memory write access violation
202
reg [`RB1:0] num_misaligned_memory;         // count misaligned memory access
203
reg          error_last;                    // error input was present in last clock cycle
204
reg          clock_enabled_last;            // clock was enabled in last clock cycle
205
reg          first_error_saved;             // an error has been detected and saved
206
reg [`CODE_ADDR_WIDTH-1:0] alu_instruction_pointer; // alu_instruction pointer is not input, but reconstructed here
207
 
208
 
209
// signals for resetting counters
210
logic reset_cpu_clock_cycles;
211
logic reset_num_instructions;
212
logic reset_num_instructions_vector;
213
logic reset_num_instructions_jump;
214
logic reset_num_errors;
215
 
216
always_comb begin
217
    // get all inputs
218
    stall = 0;
219
    stall_next = 0;
220
    debug_bits = 0;
221
    mask_off = 0;
222
    rs = instruction_in[`RS];
223
    rd = instruction_in[`RD];
224
 
225
    regmask_val = 0;
226
    if (regmask_val_in[`MASKSZ]) begin      // value missing
227
        if (write_en1 && regmask_val_in[`TAG_WIDTH-1:0] == write_tag1_in) begin
228
            regmask_val = writeport1_in;    // obtained from result bus 1 (which may be my own output)
229
        end else if (write_en2 && regmask_val_in[`TAG_WIDTH-1:0] == write_tag2_in) begin
230
            regmask_val = writeport2_in[(`MASKSZ-1):0]; // obtained from result bus 2
231
        end else begin
232
            if (regmask_used_in & valid_in) begin
233
                stall = 1;                  // operand not ready
234
                if (regmask_val_in[`TAG_WIDTH-1:0] != predict_tag1_in && regmask_val_in[`TAG_WIDTH-1:0] != predict_tag2_in) begin
235
                    stall_next = 1;         // operand not ready in next clock cycle
236
                end
237
            end
238
        end
239
    end else begin                          // value available
240
        regmask_val = regmask_val_in[(`MASKSZ-1):0];
241
    end
242
 
243
    operand1 = 0;
244
    if (operand1_in[`RB]) begin             // value missing
245
        if (operand1_in[`TAG_WIDTH-1:0] == write_tag1_in) begin
246
            operand1 = writeport1_in;       // obtained from result bus 1 (which may be my own output)
247
        end else if (write_en2 && operand1_in[`TAG_WIDTH-1:0] == write_tag2_in) begin
248
            operand1 = writeport2_in;       // obtained from result bus 2
249
        end else begin
250
            if (opr1_used_in & valid_in) begin
251
                stall = 1;                  // operand not ready
252
                debug_bits[0] = 1;
253
                if (operand1_in[`TAG_WIDTH-1:0] != predict_tag1_in && operand1_in[`TAG_WIDTH-1:0] != predict_tag2_in) begin
254
                    stall_next = 1;         // operand not ready in next clock cycle
255
                    debug_bits[1] = 1;
256
                end
257
            end
258
        end
259
    end else begin
260
        operand1 = operand1_in[`RB1:0];
261
    end
262
 
263
    operand2 = 0;
264
    if (operand2_in[`RB]) begin             // value missing
265
        if (operand2_in[`TAG_WIDTH-1:0] == write_tag1_in) begin
266
            operand2 = writeport1_in;       // obtained from result bus 1 (which may be my own output)
267
        end else if (write_en2 && operand2_in[`TAG_WIDTH-1:0] == write_tag2_in) begin
268
            operand2 =  writeport2_in;      // obtained from result bus 2
269
        end else begin
270
            stall = 1;                      // operand not ready
271
            debug_bits[2] = 1;
272
            if (operand2_in[`TAG_WIDTH-1:0] != predict_tag1_in && operand2_in[`TAG_WIDTH-1:0] != predict_tag2_in) begin
273
                stall_next = 1;             // operand not ready in next clock cycle
274
                debug_bits[3] = 1;
275
            end
276
        end
277
    end else begin                          // value available
278
        operand2 = operand2_in[`RB1:0];
279
    end
280
 
281
    // operand 3 is never missing if all instructions in this module have a constant as last operand:
282
    operand3 = operand3_in[`RB1:0];
283
    /*
284
    operand3 = 0;
285
    if (operand3_in[`RB]) begin // value missing
286
        if (operand3_in[`TAG_WIDTH-1:0] == write_tag1_in) begin
287
            operand3 = writeport1_in;  // obtained from result bus 1 (which may be my own output)
288
        end else if (write_en2 && operand3_in[`TAG_WIDTH-1:0] == write_tag2_in) begin
289
            operand3 =  writeport2_in; // obtained from result bus 2
290
        end else begin
291
            stall = 1; // operand not ready
292
            debug_bits[2] = 1;
293
            if (operand3_in[`TAG_WIDTH-1:0] != predict_tag1_in && operand3_in[`TAG_WIDTH-1:0] != predict_tag2_in) begin
294
                stall_next = 1; // operand not ready in next clock cycle
295
                debug_bits[3] = 1;
296
            end
297
        end
298
    end else begin // value available
299
        operand3 = operand3_in[`RB1:0];
300
    end*/
301
 
302
    mask_off = regmask_used_in && regmask_val[`MASKSZ] == 0 && regmask_val[0] == 0 && !mask_alternative_in;
303
 
304
    opx = opx_in;                           // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
305
    otout = ot_in[1:0];                     // operand type for output
306
    error = 0;
307
    error_parm = 0;
308
 
309
    // get port address
310
    if (operand3 < 255) begin
311
        port_address = operand3;            // immediate address
312
    end else begin
313
        port_address = operand2;            // port address from register RS
314
    end
315
 
316
 
317
    ////////////////////////////////////////////////
318
    //             Select I/O operation
319
    ////////////////////////////////////////////////
320
 
321
    result = 0;
322
    fifo_buffer_input_read_next = 0;
323
    fifo_buffer_input_reset = 0;
324
    fifo_buffer_input_reset_error = 0;
325
    serial_output_byte_in = 0;
326
    fifo_buffer_output_write = 0;
327
    fifo_buffer_output_reset = 0;
328
    fifo_buffer_output_reset_error = 0;
329
    reset_cpu_clock_cycles = 0;
330
    reset_num_instructions = 0;
331
    reset_num_instructions_vector = 0;
332
    reset_num_instructions_jump = 0;
333
    reset_num_errors = 0;
334
 
335
    if (valid_in && !stall && !stall_in) begin
336
 
337
        if (opx == `IX_INPUT) begin
338
            // input port operation
339
            debug_bits[4] = 1;
340
 
341
            case (port_address)
342
            `INPORT_RS232: begin
343
                result[7:0] = fifo_buffer_input_byte;
344
                result[8] = fifo_buffer_input_ready;
345
                result[9] = fifo_buffer_input_num > 1;
346
                fifo_buffer_input_read_next = 1;
347
            end
348
            `INPORT_RS232_STATUS: begin
349
                if (`IN_BUFFER_SIZE_LOG2 > 16 && fifo_buffer_input_num >= 2**`IN_BUFFER_SIZE_LOG2) begin
350
                    result[15:0] = 16'HFFFF;
351
                end else begin
352
                    result[`IN_BUFFER_SIZE_LOG2-1:0] = fifo_buffer_input_num[`IN_BUFFER_SIZE_LOG2-1:0];
353
                end
354
                result[16] = fifo_buffer_input_overflow;
355
                result[17] = UART_RX_error;
356
            end
357
            `OUTPORT_RS232_STATUS: begin
358
                if (`OUT_BUFFER_SIZE_LOG2 > 16 && fifo_buffer_output_num >= 2**`OUT_BUFFER_SIZE_LOG2) begin
359
                    result[15:0] = 16'HFFFF;
360
                end else begin
361
                    result[`OUT_BUFFER_SIZE_LOG2-1:0] = fifo_buffer_output_num[`OUT_BUFFER_SIZE_LOG2-1:0];
362
                end
363
                result[16] = fifo_buffer_output_overflow;
364
                result[18] = ! (&fifo_buffer_output_num);
365
            end
366
            default: begin
367
                // unknown port address
368
                error_parm = 1;
369
            end
370
            endcase
371
 
372
        end else if (opx == `IX_OUTPUT) begin
373
 
374
            // output port operation
375
            debug_bits[5] = 1;
376
            case (port_address)
377
            `OUTPORT_RS232: begin
378
                serial_output_byte_in = operand1[7:0];
379
                fifo_buffer_output_write = 1;
380
            end
381
            `OUTPORT_RS232_STATUS: begin
382
                fifo_buffer_output_reset = operand1[0];
383
                fifo_buffer_output_reset_error = operand1[1];
384
            end
385
            `INPORT_RS232_STATUS: begin
386
                fifo_buffer_input_reset = operand1[0];
387
                fifo_buffer_input_reset_error = operand1[1];
388
            end
389
            default: begin
390
                // unknown port address
391
                error_parm = 1;
392
            end
393
            endcase
394
 
395
        end else if (opx == `IX_READ_CAPABILITIES) begin
396
            // read capabilities registers, etc.
397
            case (rs)
398
            0:  result = "A";                                 // Microprocessor brand ID
399
            1:  result = 20'h10000;                           // Microprocessor version
400
            2:  result = capab_disable_errors;                // Capab2: disable error traps
401
            4:  result = {1'b1,{(`CODE_ADDR_WIDTH+2){1'b0}}}; // Code memory size, (bytes)
402
            5:  result = {1'b1,{(`DATA_ADDR_WIDTH){1'b0}}};   // Data memory size, (bytes)
403
            8:
404
            `ifdef SUPPORT_64BIT
405
                result = 4'b1111;                             // support for operand sizes
406
            `else
407
                result = 4'b0111;
408
            `endif
409
            9:  result = `NUM_VECTOR_UNITS > 0 ? 4'b1111 : 0; // support for operand sizes in vectors
410
            12: result = `NUM_VECTOR_UNITS * 8;               // maximum vector length
411
            13, 14, 15: result = `NUM_VECTOR_UNITS * 8;       // maximum vector length for permute, compress, expand, etc.
412
            default: result = 0;
413
            endcase
414
 
415
        end else if (opx == `IX_WRITE_CAPABILITIES) begin
416
            // write capabilities registers, etc.
417
            result = operand2;                                // any capabilities register written below
418
 
419
        end else if ((opx & -2) == `IX_READ_PERF) begin
420
            // read_perf and read_perfs
421
            case (rs)
422
            0:  begin  // reset all performance counters
423
                    reset_cpu_clock_cycles = operand3_in[0];
424
                    reset_num_instructions = operand3_in[1];
425
                    reset_num_instructions_vector = operand3_in[2];
426
                    reset_num_instructions_jump = operand3_in[3];
427
                    reset_num_errors = operand3_in[4];
428
                end
429
            1:  begin
430
                    result = cpu_clock_cycles;             // count CPU clock cycles
431
                    if (operand3_in[7:0] == 0) reset_cpu_clock_cycles = 1;
432
                end
433
            2:  begin                                      // count instructions
434
                case (operand3_in[7:0])
435
                0: begin
436
                       result = num_instructions;          // count instructions
437
                       reset_num_instructions = 1;
438
                   end
439
                1: result = num_instructions;              // count instructions
440
                2: result = num_instructions_2size;        // count double size instructions
441
                3: result = num_instructions_2size;        // count double size instructions
442
                4: result = num_instructions_gp;           // count instructions with g.p. registers
443
                5: result = num_instructions_gp_mask0;     // count instructions with g.p. registers and mask = 0
444
                endcase
445
                end
446
            3:  begin
447
                    result = num_instructions_vector;      // count instructions with vector registers
448
                    if (operand3_in[7:0] == 0) reset_num_instructions_vector = 1;
449
                end
450
            4:  result = 0;                                // vector registers in use
451
            5:  begin                                      // jump instructions
452
                case (operand3_in[7:0])
453
                0: begin
454
                       result = num_jump_call_return;      // count instructions
455
                       reset_num_instructions_jump = 1;
456
                   end
457
                1: result = num_jump_call_return;          // count control transfer instructions
458
                2: result = num_jump_call_direct;          // count direct unconditional jumps and calls
459
                3: result = num_jump_call_indirect;        // count indirect jumps and calls
460
                4: result = num_jump_conditional;          // count conditional jumps
461
                endcase
462
                end
463
            16: begin                                      // count errors
464
                case (operand3_in[7:0])
465
                0: begin
466
                       reset_num_errors = 1;
467
                   end
468
                1:  result = num_unknown_instruction;
469
                2:  result = num_wrong_operands;
470
                3:  result = num_array_overflow;
471
                4:  result = num_read_violation;
472
                5:  result = num_write_violation;
473
                6:  result = num_misaligned_memory;
474
                62: result = first_error;                  // error type for first error
475
                63: result = first_error_address;          // code address of first error
476
                endcase
477
                end
478
 
479
            endcase
480
        end else begin
481
            error = 1;                                     // unknown instruction
482
        end
483
    end
484
 
485
    // output for debugger
486
    debug_bits[14:8] = opx;
487
 
488
    debug_bits[16] = stall;                  // waiting for operands
489
    debug_bits[17] = stall_next;             // will be waiting for operands in next clock cycle
490
    debug_bits[19] = error;                  // unknown or illegal operation
491
    debug_bits[20] = valid_in;               // inout is enabled
492
    debug_bits[21] = fifo_buffer_input_read_next;
493
    debug_bits[22] = fifo_buffer_output_write;
494
    debug_bits[31:24] = port_address[7:0];
495
    /*
496
    debug_bits[23:20] = error_number_in;
497
    debug_bits[31:24] = num_unknown_instruction[7:0];
498
    */
499
 
500
end
501
 
502
 
503
// output
504
always_ff @(posedge clock) if (clock_enable) begin
505
    if (!valid_in) begin
506
        register_write_out <= 0;
507
        // note: the FPGA has no internal tri-state buffers. We need to simulate result bus by or'ing outputs
508
        result_out <= 0;
509
        register_a_out <= 0;
510
        tag_val_out <= 0;
511
 
512
    // stall_in must disable the output to avoid executing the same instruction twice)
513
    end else if (stall || stall_in || result_type_in != `RESULT_REG) begin
514
        register_write_out <= 0;
515
        result_out <= 0;
516
        register_a_out <= 0;
517
        tag_val_out <= 0;
518
 
519
    end else begin
520
        // register result from input instruction or read_capabilities, etc.
521
        case (otout)
522
        0: result_out <= result[7:0];
523
        1: result_out <= result[15:0];
524
        2: result_out <= result[31:0];
525
        3: result_out <= result[`RB1:0];
526
        endcase
527
        register_write_out <= ~reset;
528
        register_a_out <= {1'b0,rd};
529
        tag_val_out <= tag_val_in;
530
    end
531
 
532
    if (result_type_in == `RESULT_SYS) begin
533
        // write system register
534
        if (opx == `IX_WRITE_CAPABILITIES && rd == 2) capab_disable_errors <= result;
535
    end
536
    if (reset) begin                                       // reset capabilities registers
537
        capab_disable_errors <= 0;
538
    end
539
 
540
    valid_out <= !stall & valid_in & !reset;
541
    stall_out <=  stall & valid_in & !reset;
542
    stall_next_out <= stall_next & valid_in & !reset;
543
    nojump_out <= (opx == `IX_READ_PERFS) & valid_in;      // resume after serializing
544
    error_out <= error & valid_in & !reset;                // unknown instruction
545
    error_parm_out <= error_parm & valid_in & !reset;      // wrong parameter
546
    uart_cts_out <= 1;                                     // UART clear to send
547
    debug_out <= debug_bits;                               // output for debugger
548
end
549
 
550
 
551
// update performance counters
552
always_ff @(posedge clock) if (clock_enable) begin
553
    cpu_clock_cycles <= cpu_clock_cycles + 1;
554
    if (instruction_valid_in) begin
555
        num_instructions <= num_instructions + 1 + fast_jump_in;
556
        if (instruction_in[`IL] == 2) num_instructions_2size <= num_instructions_2size + 1;
557
        if (instruction_in[`IL] == 3) num_instructions_3size <= num_instructions_3size + 1;
558
        if (vector_in) begin
559
            num_instructions_vector <= num_instructions_vector + 1;
560
        end else begin
561
            num_instructions_gp <= num_instructions_gp + 1;
562
            if (mask_off) num_instructions_gp_mask0 <= num_instructions_gp_mask0 + 1;
563
        end
564
        if (category_in == `CAT_JUMP) begin                // jump instructions
565
            num_jump_call_return <= num_jump_call_return + 1 + fast_jump_in;
566
            if (opj_in <= `IJ_LAST_CONDITIONAL) num_jump_conditional <= num_jump_conditional + 1;
567
            else num_jump_call_indirect <= num_jump_call_indirect + 1;
568
        end
569
    end
570
    if (fast_jump_in) begin                                // fast jump/call/return bypassing pipeline
571
        num_jump_call_direct <= num_jump_call_direct + 1;
572
        if (!(instruction_valid_in && category_in == `CAT_JUMP)) begin
573
            num_jump_call_return <= num_jump_call_return + 1; // count also total jumps, except if counted above
574
        end
575
    end
576
 
577
    // reset counters
578
    if (reset_cpu_clock_cycles | reset) begin
579
        cpu_clock_cycles <= 0;
580
    end
581
    if (reset_num_instructions | reset) begin
582
        num_instructions <= 0;
583
        num_instructions_2size <= 0;
584
        num_instructions_3size <= 0;
585
        num_instructions_gp <= 0;
586
        num_instructions_gp_mask0 <= 0;
587
    end
588
    if (reset_num_instructions_vector | reset) begin
589
        num_instructions_vector <= 0;
590
    end
591
    if (reset_num_instructions_jump | reset) begin
592
        num_jump_call_return <= 0;       // count control transfer instructions
593
        num_jump_call_direct <= 0;       // count direct unconditional jumps and calls
594
        num_jump_call_indirect <= 0;     // count indirect jumps and calls
595
        num_jump_conditional <= 0;       // count conditional jumps
596
    end
597
end
598
 
599
// Error detection. This is not controlled by clock enable because clock enable may stop when error is detected
600
always_ff @(posedge clock) begin
601
    error_last <= |errors_detect_in;     // error detected in last clock cycle
602
    clock_enabled_last <= clock_enable;  // clock was enabled in last clock cycle. new instruction encountered
603
 
604
    // A new error is detected if there was no error signal in the last clock cycle
605
    // of if clock_enable has allowed the execution of a new instruction
606
    if (|errors_detect_in && (clock_enabled_last || !error_last)) begin
607
        // a new error is detected. count it only once
608
        if      (errors_detect_in[0]) num_unknown_instruction <= num_unknown_instruction + 1;
609
        else if (errors_detect_in[1]) num_wrong_operands <= num_wrong_operands + 1;
610
        else if (errors_detect_in[2]) num_array_overflow <= num_array_overflow + 1;
611
        else if (errors_detect_in[3]) num_read_violation <= num_read_violation + 1;
612
        else if (errors_detect_in[4]) num_write_violation <= num_write_violation + 1;
613
        else if (errors_detect_in[5]) num_misaligned_memory <= num_misaligned_memory + 1;
614
    end
615
 
616
    // remember first error
617
    if (|errors_detect_in) begin
618
        if (!first_error_saved) begin
619
            if  (errors_detect_in[0]) begin
620
                first_error <= 1;
621
                first_error_address <= alu_instruction_pointer;
622
            end else if (errors_detect_in[1]) begin
623
                first_error <= 2;
624
                if (call_stack_overflow) first_error_address <= fetch_instruction_pointer;
625
                else first_error_address <= alu_instruction_pointer;
626
            end else if (errors_detect_in[2]) begin
627
                first_error <= 3;
628
                first_error_address <= dataread_instruction_pointer;
629
            end else if (errors_detect_in[3]) begin
630
                first_error <= 4;
631
                first_error_address <= dataread_instruction_pointer;
632
            end else if (errors_detect_in[4]) begin
633
                first_error <= 5;
634
                first_error_address <= dataread_instruction_pointer;
635
            end else if (errors_detect_in[5]) begin
636
                first_error <= 6;
637
                first_error_address <= dataread_instruction_pointer;
638
            end
639
        end
640
        first_error_saved <= 1;
641
    end
642
 
643
    if (reset_num_errors | reset) begin
644
        // reset error counters
645
        num_unknown_instruction <= 0;    // count unknown instruction
646
        num_wrong_operands <= 0;         // count wrong operands for instructions
647
        num_array_overflow <= 0;         // count array index out of range
648
        num_read_violation <= 0;         // count memory read access violation
649
        num_write_violation <= 0;        // count memory write access violation
650
        num_misaligned_memory <= 0;      // count misaligned memory access
651
        first_error <= 0;
652
        first_error_address <= 0;
653
        first_error_saved <= 0;
654
    end
655
    if (clear_error_in) begin
656
        first_error_saved <= 0;          // debugger clear error
657
    end
658
 
659
    // reconstruct alu_instruction_pointer:
660
    if (clock_enable & dataread_valid) begin
661
        alu_instruction_pointer <= dataread_instruction_pointer;
662
    end
663
 
664
end
665
 
666
 
667
// implement uart receiver
668
UART_RX UART_RX_inst (
669
    .reset(reset | fifo_buffer_input_reset | fifo_buffer_input_reset_error), // reset
670
    .clock(clock),                                         // clock at `CLOCK_RATE
671
    .rx_in(uart_bit_in),                                   // RX input
672
    .receive_complete_out(UART_RX_receive_complete),       // byte received. Will be high for 1 clock cycle after the middle of the stop bit
673
    .error_out(UART_RX_error),                             // transmission error. Remains high until reset in case of error
674
    .byte_out(UART_RX_byte_out)                            // byte output
675
);
676
 
677
// implement uart transmitter
678
UART_TX UART_TX_inst (
679
    .reset(reset | fifo_buffer_output_reset | fifo_buffer_output_reset_error), // reset
680
   .clock(clock),                                          // clock at `CLOCK_RATE
681
   .start_in(fifo_buffer_output_ready),                    // command to send one byte
682
   .byte_in(fifo_buffer_output_byte),                      // byte input
683
   .active_out(UART_TX_active),                            // is busy
684
   .tx_out(uart_bit_out),                                  // TX output
685
   .done_out(UART_TX_done)                                 // will be high for one clock cycle shortly before the end of the stop bit
686
);
687
 
688
// implement fifo buffer for receiver
689
fifo_buffer #(.size_log2(`IN_BUFFER_SIZE_LOG2))
690
fifo_buffer_input (
691
    .reset(reset | fifo_buffer_input_reset),               // reset everything
692
    .reset_error(reset | fifo_buffer_input_reset_error),   // clear error flags
693
    .clock(clock),                                         // clock at `CLOCK_RATE
694
    .read_next(fifo_buffer_input_read_next & clock_enable),// read next byte from buffer
695
    .write(UART_RX_receive_complete),                      // write one byte to buffer
696
    .byte_in(UART_RX_byte_out),                            // serial byte input
697
    .byte_out(fifo_buffer_input_byte),                     // serial byte output prefetched
698
    .data_ready_out(fifo_buffer_input_ready),              // the buffer contains at least one byte
699
    .overflow(fifo_buffer_input_overflow),                 // attempt to write to full buffer
700
    .underflow(fifo_buffer_output_underflow),              // attempt to read from empty buffer
701
    .num(fifo_buffer_input_num)                            // number of bytes currently in buffer
702
);
703
 
704
// implement fifo buffer for transmitter
705
fifo_buffer #(.size_log2(`OUT_BUFFER_SIZE_LOG2))
706
fifo_buffer_output (
707
    .reset(reset | fifo_buffer_output_reset),              // reset everything
708
    .reset_error(reset | fifo_buffer_output_reset_error),  // clear error flags
709
    .clock(clock),                                         // clock at `CLOCK_RATE
710
    .read_next(UART_TX_done),                              // read next byte from buffer
711
    .write(fifo_buffer_output_write & clock_enable),       // write one byte to buffer
712
    .byte_in(serial_output_byte_in),                       // serial byte input
713
    .byte_out(fifo_buffer_output_byte),                    // serial byte output prefetched
714
    .data_ready_out(fifo_buffer_output_ready),             // the buffer contains at least one byte
715
    .overflow(fifo_buffer_output_overflow),                // attempt to write to full buffer
716
    .underflow(fifo_buffer_output_underflow),              // attempt to read from empty buffer
717
    .num(fifo_buffer_output_num)                           // number of bytes currently in buffer
718
);
719
 
720
 
721
endmodule

powered by: WebSVN 2.1.0

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