URL
https://opencores.org/ocsvn/forwardcom/forwardcom/trunk
Subversion Repositories forwardcom
[/] [forwardcom/] [trunk/] [in_out_ports.sv] - Rev 138
Go to most recent revision | Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////////////////// Engineer: Agner Fog//// Create Date: 2020-11-16// Last modified: 2021-08-03// Module Name: in_out_ports// Project Name: ForwardCom soft core// Target Devices: Artix 7// Tool Versions: Vivado v. 2020.1// License: CERN-OHL-W v. 2 or later// Description: Input and output ports, as well as reading and writing of special// registers, including capabilities registers and performance counter registers///////////////////////////////////////////////////////////////////////////////////* Input and output ports:All input and output bits beyond the specified operand size are set to zero.The port address can have up to 64 bits regardless of the specified operand size.The following input and output ports are currently defined:-----------------------------------------------------------RS232 serial input and output.Transmission settings: 8 data bits, one stop bit, no parity, no flow control.The BAUD rate is currently defined in the file defines.vhInput port 8. Serial input:Read one byte from RS232 serial input. Non-blockingThe following value is returned:bit 0-7: Received data (zero if input buffer empty)bit 8: Data valid. Unreliable!bit 9: More data ready: The input buffer contains at least one more byte ready to readbit 12: Buffer overflow error. Data has been lost due to input buffer overflowbit 13: Frame error. Error detected in start bit or stop bit. May be due to noise or wrong BAUD rateInput port 9. Serial input status:bit 0-15: Number of bytes currently in input bufferbit 16: Buffer overflow error. Data has been lost due to input buffer overflowbit 17: Frame error. Error detected in start bit or stop bit. May be due to noise or wrong BAUD rateOutput port 9. Serial input control:bit 0: Clear buffer. Delete all data currently in the input buffer, and clear error flagsbit 1: Clear error flags but keep data.The error bits remain high after an error condition until reset by this or by system resetOutput port 10. Serial output:Write one byte to RS232 serial output.bit 0-7: Data to writeOther bits are reserved.Input port 11. Serial output status:bit 0-15: Number of bytes currently in output bufferbit 16: Buffer overflow error. Data has been lost due to output buffer overflowbit 18: Ready. The output buffer has enough space to receive at least one more byteOutput port 11. Serial output control:bit 0: Clear buffer. Delete all data currently in the output buffer, and clear error flagsbit 1: Clear error flags but keep data.The error bits remain high after an error condition until reset by this or by system resetThe following special registers are currently defined:-----------------------------------------------------------Capabilities registers 0, 1, 4, 5Performance counter registers 1 - 5, and 16*/`include "defines.vh"module in_out_ports (input clock, // system clock (100 MHz)input clock_enable, // clock enable. Used when single-steppinginput reset, // system resetinput valid_in, // data from previous stage readyinput stall_in, // pipeline is stalledinput [31:0] instruction_in, // current instruction, up to 3 words long. Only first word used hereinput [`TAG_WIDTH-1:0] tag_val_in, // instruction tag valueinput [1:0] category_in, // 00: multiformat, 01: single format, 10: jumpinput [1:0] result_type_in, // type of result: 0: register, 1: system register, 2: memory, 3: other or nothinginput mask_alternative_in, // mask register used for alternative purposesinput vector_in, // this is a vector instructioninput [6:0] opx_in, // operation ID in execution unit. This is mostly equal to op1 for multiformat instructionsinput [5:0] opj_in, // operation ID for conditional jump instructionsinput [2:0] ot_in, // operand typeinput regmask_used_in, // mask register is usedinput uart_bit_in, // serial inputinput uart_rts_in, // ready to send input (not used)// monitor result buses:input write_en1, // a result is written to writeport1input [`TAG_WIDTH-1:0] write_tag1_in, // tag of result inwriteport1input [`RB1:0] writeport1_in, // result bus 1input write_en2, // a result is written to writeport2input [`TAG_WIDTH-1:0] write_tag2_in, // tag of result inwriteport2input [`RB1:0] writeport2_in, // result bus 2input [`TAG_WIDTH-1:0] predict_tag1_in, // result tag value on writeport1 in next clock cycleinput [`TAG_WIDTH-1:0] predict_tag2_in, // result tag value on writeport2 in next clock cycle// Register values sampled from result bus in previous stagesinput [`RB:0] operand1_in, // first register operand RD or RUinput [`RB:0] operand2_in, // second register operand RSinput [`RB:0] operand3_in, // last register operand RTinput [`MASKSZ:0] regmask_val_in, // mask registerinput opr1_used_in, // operand1_in is needed// signals used for performance monitoring and error detectioninput instruction_valid_in, // instruction is valid but possibly going to a different exe unitinput fast_jump_in, // a jump is bypassing the pipelineinput [`N_ERROR_TYPES-1:0] errors_detect_in, // one bit for each type of error detected// instruction pointer at position of errorinput [`CODE_ADDR_WIDTH-1:0] fetch_instruction_pointer,input [`CODE_ADDR_WIDTH-1:0] dataread_instruction_pointer,input dataread_valid, // used when reconstructing alu_instruction_pointerinput call_stack_overflow, // used for differentiating errors_detect_in[1]input clear_error_in, // debugger clear error// outputsoutput reg valid_out, // for debug display: in_out is activeoutput reg register_write_out,output reg [5:0] register_a_out, // register to writeoutput reg [`RB1:0] result_out, // value to write to registeroutput reg [`TAG_WIDTH-1:0] tag_val_out,// instruction tag valueoutput reg nojump_out, // serializing instruction finishedoutput reg stall_out, // alu is waiting for an operand or not ready to receive a new instructionoutput reg stall_next_out, // alu will be waiting in next clock cycleoutput reg error_out, // unknown instructionoutput reg error_parm_out, // wrong parameter for instructionoutput reg uart_bit_out, // serial outputoutput reg uart_cts_out, // serial clear to sendoutput reg [`N_ERROR_TYPES-1:0] capab_disable_errors, // capab2 register: disable errorsoutput reg [3:0] first_error, // error type for first erroroutput reg [`CODE_ADDR_WIDTH-1:0] first_error_address, // code address of first erroroutput reg [31:0] debug_out // debug information);logic [`RB1:0] operand1; // first register operand RD or RU. bit `RB is 1 if invalidlogic [`RB1:0] operand2; // second register operand RS. bit `RB is 1 if invalidlogic [`RB1:0] operand3; // last register operand RT. bit `RB is 1 if invalidlogic [`MASKSZ:0] regmask_val; // mask registerlogic [1:0] otout; // operand type for outputlogic [`RB1:0] result; // result for outputlogic [6:0] opx; // operation ID in execution unit. This is mostly equal to op1 for multiformat instructionslogic [4:0] rs; // RS field in instructionlogic [4:0] rd; // RD field in instructionlogic stall; // waiting for operandslogic stall_next; // will be waiting for operands in next clock cyclelogic error; // unknown instructionlogic error_parm; // wrong parameter for instructionlogic [`RB1:0] port_address; // address of input or output port// submodules signalsreg UART_RX_receive_complete;reg UART_RX_error;reg [7:0] UART_RX_byte_out;reg UART_TX_active;reg UART_TX_tx_out;reg UART_TX_done;reg [7:0] fifo_buffer_input_byte; // serial byte output prefetchedreg fifo_buffer_input_ready; // the buffer contains at least one bytereg fifo_buffer_input_overflow; // attempt to write to full bufferreg fifo_buffer_input_underflow; // attempt to read from empty bufferreg [`IN_BUFFER_SIZE_LOG2-1:0] fifo_buffer_input_num; // number of bytes currently in input bufferreg [7:0] serial_output_byte_in; // serial byte outputreg [7:0] fifo_buffer_output_byte; // serial byte output prefetched from bufferreg fifo_buffer_output_ready; // the buffer contains at least one bytereg fifo_buffer_output_overflow; // attempt to write to full bufferreg fifo_buffer_output_underflow; // attempt to read from empty bufferreg [`OUT_BUFFER_SIZE_LOG2-1:0] fifo_buffer_output_num; // number of bytes currently in output bufferlogic fifo_buffer_input_read_next;logic fifo_buffer_input_reset;logic fifo_buffer_input_reset_error;logic fifo_buffer_output_write;logic fifo_buffer_output_reset;logic fifo_buffer_output_reset_error;logic mask_off;// temporary debug infologic [31:0] debug_bits;// performance countersreg [`RB1:0] cpu_clock_cycles; // count CPU clock cyclesreg [`RB1:0] num_instructions; // count instructionsreg [`RB1:0] num_instructions_2size; // count double size instructionsreg [`RB1:0] num_instructions_3size; // count triple size instructionsreg [`RB1:0] num_instructions_gp; // count instructions with g.p. registersreg [`RB1:0] num_instructions_gp_mask0; // count instructions with g.p. registers and mask = 0reg [`RB1:0] num_instructions_vector; // count instructions with vector registersreg [`RB1:0] num_jump_call_return; // count control transfer instructionsreg [`RB1:0] num_jump_call_direct; // count direct unconditional jumps and callsreg [`RB1:0] num_jump_call_indirect; // count indirect jumps and callsreg [`RB1:0] num_jump_conditional; // count conditional jumpsreg [`RB1:0] num_unknown_instruction; // count unknown instructionreg [`RB1:0] num_wrong_operands; // count wrong operands for instructionsreg [`RB1:0] num_array_overflow; // count array index out of rangereg [`RB1:0] num_read_violation; // count memory read access violationreg [`RB1:0] num_write_violation; // count memory write access violationreg [`RB1:0] num_misaligned_memory; // count misaligned memory accessreg error_last; // error input was present in last clock cyclereg clock_enabled_last; // clock was enabled in last clock cyclereg first_error_saved; // an error has been detected and savedreg [`CODE_ADDR_WIDTH-1:0] alu_instruction_pointer; // alu_instruction pointer is not input, but reconstructed here// signals for resetting counterslogic reset_cpu_clock_cycles;logic reset_num_instructions;logic reset_num_instructions_vector;logic reset_num_instructions_jump;logic reset_num_errors;always_comb begin// get all inputsstall = 0;stall_next = 0;debug_bits = 0;mask_off = 0;rs = instruction_in[`RS];rd = instruction_in[`RD];regmask_val = 0;if (regmask_val_in[`MASKSZ]) begin // value missingif (write_en1 && regmask_val_in[`TAG_WIDTH-1:0] == write_tag1_in) beginregmask_val = writeport1_in; // obtained from result bus 1 (which may be my own output)end else if (write_en2 && regmask_val_in[`TAG_WIDTH-1:0] == write_tag2_in) beginregmask_val = writeport2_in[(`MASKSZ-1):0]; // obtained from result bus 2end else beginif (regmask_used_in & valid_in) beginstall = 1; // operand not readyif (regmask_val_in[`TAG_WIDTH-1:0] != predict_tag1_in && regmask_val_in[`TAG_WIDTH-1:0] != predict_tag2_in) beginstall_next = 1; // operand not ready in next clock cycleendendendend else begin // value availableregmask_val = regmask_val_in[(`MASKSZ-1):0];endoperand1 = 0;if (operand1_in[`RB]) begin // value missingif (operand1_in[`TAG_WIDTH-1:0] == write_tag1_in) beginoperand1 = writeport1_in; // obtained from result bus 1 (which may be my own output)end else if (write_en2 && operand1_in[`TAG_WIDTH-1:0] == write_tag2_in) beginoperand1 = writeport2_in; // obtained from result bus 2end else beginif (opr1_used_in & valid_in) beginstall = 1; // operand not readydebug_bits[0] = 1;if (operand1_in[`TAG_WIDTH-1:0] != predict_tag1_in && operand1_in[`TAG_WIDTH-1:0] != predict_tag2_in) beginstall_next = 1; // operand not ready in next clock cycledebug_bits[1] = 1;endendendend else beginoperand1 = operand1_in[`RB1:0];endoperand2 = 0;if (operand2_in[`RB]) begin // value missingif (operand2_in[`TAG_WIDTH-1:0] == write_tag1_in) beginoperand2 = writeport1_in; // obtained from result bus 1 (which may be my own output)end else if (write_en2 && operand2_in[`TAG_WIDTH-1:0] == write_tag2_in) beginoperand2 = writeport2_in; // obtained from result bus 2end else beginstall = 1; // operand not readydebug_bits[2] = 1;if (operand2_in[`TAG_WIDTH-1:0] != predict_tag1_in && operand2_in[`TAG_WIDTH-1:0] != predict_tag2_in) beginstall_next = 1; // operand not ready in next clock cycledebug_bits[3] = 1;endendend else begin // value availableoperand2 = operand2_in[`RB1:0];end// operand 3 is never missing if all instructions in this module have a constant as last operand:operand3 = operand3_in[`RB1:0];/*operand3 = 0;if (operand3_in[`RB]) begin // value missingif (operand3_in[`TAG_WIDTH-1:0] == write_tag1_in) beginoperand3 = writeport1_in; // obtained from result bus 1 (which may be my own output)end else if (write_en2 && operand3_in[`TAG_WIDTH-1:0] == write_tag2_in) beginoperand3 = writeport2_in; // obtained from result bus 2end else beginstall = 1; // operand not readydebug_bits[2] = 1;if (operand3_in[`TAG_WIDTH-1:0] != predict_tag1_in && operand3_in[`TAG_WIDTH-1:0] != predict_tag2_in) beginstall_next = 1; // operand not ready in next clock cycledebug_bits[3] = 1;endendend else begin // value availableoperand3 = operand3_in[`RB1:0];end*/mask_off = regmask_used_in && regmask_val[`MASKSZ] == 0 && regmask_val[0] == 0 && !mask_alternative_in;opx = opx_in; // operation ID in execution unit. This is mostly equal to op1 for multiformat instructionsotout = ot_in[1:0]; // operand type for outputerror = 0;error_parm = 0;// get port addressif (operand3 < 255) beginport_address = operand3; // immediate addressend else beginport_address = operand2; // port address from register RSend////////////////////////////////////////////////// Select I/O operation////////////////////////////////////////////////result = 0;fifo_buffer_input_read_next = 0;fifo_buffer_input_reset = 0;fifo_buffer_input_reset_error = 0;serial_output_byte_in = 0;fifo_buffer_output_write = 0;fifo_buffer_output_reset = 0;fifo_buffer_output_reset_error = 0;reset_cpu_clock_cycles = 0;reset_num_instructions = 0;reset_num_instructions_vector = 0;reset_num_instructions_jump = 0;reset_num_errors = 0;if (valid_in && !stall && !stall_in) beginif (opx == `IX_INPUT) begin// input port operationdebug_bits[4] = 1;case (port_address)`INPORT_RS232: beginresult[7:0] = fifo_buffer_input_byte;result[8] = fifo_buffer_input_ready;result[9] = fifo_buffer_input_num > 1;fifo_buffer_input_read_next = 1;end`INPORT_RS232_STATUS: beginif (`IN_BUFFER_SIZE_LOG2 > 16 && fifo_buffer_input_num >= 2**`IN_BUFFER_SIZE_LOG2) beginresult[15:0] = 16'HFFFF;end else beginresult[`IN_BUFFER_SIZE_LOG2-1:0] = fifo_buffer_input_num[`IN_BUFFER_SIZE_LOG2-1:0];endresult[16] = fifo_buffer_input_overflow;result[17] = UART_RX_error;end`OUTPORT_RS232_STATUS: beginif (`OUT_BUFFER_SIZE_LOG2 > 16 && fifo_buffer_output_num >= 2**`OUT_BUFFER_SIZE_LOG2) beginresult[15:0] = 16'HFFFF;end else beginresult[`OUT_BUFFER_SIZE_LOG2-1:0] = fifo_buffer_output_num[`OUT_BUFFER_SIZE_LOG2-1:0];endresult[16] = fifo_buffer_output_overflow;result[18] = ! (&fifo_buffer_output_num);enddefault: begin// unknown port addresserror_parm = 1;endendcaseend else if (opx == `IX_OUTPUT) begin// output port operationdebug_bits[5] = 1;case (port_address)`OUTPORT_RS232: beginserial_output_byte_in = operand1[7:0];fifo_buffer_output_write = 1;end`OUTPORT_RS232_STATUS: beginfifo_buffer_output_reset = operand1[0];fifo_buffer_output_reset_error = operand1[1];end`INPORT_RS232_STATUS: beginfifo_buffer_input_reset = operand1[0];fifo_buffer_input_reset_error = operand1[1];enddefault: begin// unknown port addresserror_parm = 1;endendcaseend else if (opx == `IX_READ_CAPABILITIES) begin// read capabilities registers, etc.case (rs)0: result = "A"; // Microprocessor brand ID1: result = 20'h10000; // Microprocessor version2: result = capab_disable_errors; // Capab2: disable error traps4: result = {1'b1,{(`CODE_ADDR_WIDTH+2){1'b0}}}; // Code memory size, (bytes)5: result = {1'b1,{(`DATA_ADDR_WIDTH){1'b0}}}; // Data memory size, (bytes)8:`ifdef SUPPORT_64BITresult = 4'b1111; // support for operand sizes`elseresult = 4'b0111;`endif9: result = `NUM_VECTOR_UNITS > 0 ? 4'b1111 : 0; // support for operand sizes in vectors12: result = `NUM_VECTOR_UNITS * 8; // maximum vector length13, 14, 15: result = `NUM_VECTOR_UNITS * 8; // maximum vector length for permute, compress, expand, etc.default: result = 0;endcaseend else if (opx == `IX_WRITE_CAPABILITIES) begin// write capabilities registers, etc.result = operand2; // any capabilities register written belowend else if ((opx & -2) == `IX_READ_PERF) begin// read_perf and read_perfscase (rs)0: begin // reset all performance countersreset_cpu_clock_cycles = operand3_in[0];reset_num_instructions = operand3_in[1];reset_num_instructions_vector = operand3_in[2];reset_num_instructions_jump = operand3_in[3];reset_num_errors = operand3_in[4];end1: beginresult = cpu_clock_cycles; // count CPU clock cyclesif (operand3_in[7:0] == 0) reset_cpu_clock_cycles = 1;end2: begin // count instructionscase (operand3_in[7:0])0: beginresult = num_instructions; // count instructionsreset_num_instructions = 1;end1: result = num_instructions; // count instructions2: result = num_instructions_2size; // count double size instructions3: result = num_instructions_2size; // count double size instructions4: result = num_instructions_gp; // count instructions with g.p. registers5: result = num_instructions_gp_mask0; // count instructions with g.p. registers and mask = 0endcaseend3: beginresult = num_instructions_vector; // count instructions with vector registersif (operand3_in[7:0] == 0) reset_num_instructions_vector = 1;end4: result = 0; // vector registers in use5: begin // jump instructionscase (operand3_in[7:0])0: beginresult = num_jump_call_return; // count instructionsreset_num_instructions_jump = 1;end1: result = num_jump_call_return; // count control transfer instructions2: result = num_jump_call_direct; // count direct unconditional jumps and calls3: result = num_jump_call_indirect; // count indirect jumps and calls4: result = num_jump_conditional; // count conditional jumpsendcaseend16: begin // count errorscase (operand3_in[7:0])0: beginreset_num_errors = 1;end1: result = num_unknown_instruction;2: result = num_wrong_operands;3: result = num_array_overflow;4: result = num_read_violation;5: result = num_write_violation;6: result = num_misaligned_memory;62: result = first_error; // error type for first error63: result = first_error_address; // code address of first errorendcaseendendcaseend else beginerror = 1; // unknown instructionendend// output for debuggerdebug_bits[14:8] = opx;debug_bits[16] = stall; // waiting for operandsdebug_bits[17] = stall_next; // will be waiting for operands in next clock cycledebug_bits[19] = error; // unknown or illegal operationdebug_bits[20] = valid_in; // inout is enableddebug_bits[21] = fifo_buffer_input_read_next;debug_bits[22] = fifo_buffer_output_write;debug_bits[31:24] = port_address[7:0];/*debug_bits[23:20] = error_number_in;debug_bits[31:24] = num_unknown_instruction[7:0];*/end// outputalways_ff @(posedge clock) if (clock_enable) beginif (!valid_in) beginregister_write_out <= 0;// note: the FPGA has no internal tri-state buffers. We need to simulate result bus by or'ing outputsresult_out <= 0;register_a_out <= 0;tag_val_out <= 0;// stall_in must disable the output to avoid executing the same instruction twice)end else if (stall || stall_in || result_type_in != `RESULT_REG) beginregister_write_out <= 0;result_out <= 0;register_a_out <= 0;tag_val_out <= 0;end else begin// register result from input instruction or read_capabilities, etc.case (otout)0: result_out <= result[7:0];1: result_out <= result[15:0];2: result_out <= result[31:0];3: result_out <= result[`RB1:0];endcaseregister_write_out <= ~reset;register_a_out <= {1'b0,rd};tag_val_out <= tag_val_in;endif (result_type_in == `RESULT_SYS) begin// write system registerif (opx == `IX_WRITE_CAPABILITIES && rd == 2) capab_disable_errors <= result;endif (reset) begin // reset capabilities registerscapab_disable_errors <= 0;endvalid_out <= !stall & valid_in & !reset;stall_out <= stall & valid_in & !reset;stall_next_out <= stall_next & valid_in & !reset;nojump_out <= (opx == `IX_READ_PERFS) & valid_in; // resume after serializingerror_out <= error & valid_in & !reset; // unknown instructionerror_parm_out <= error_parm & valid_in & !reset; // wrong parameteruart_cts_out <= 1; // UART clear to senddebug_out <= debug_bits; // output for debuggerend// update performance countersalways_ff @(posedge clock) if (clock_enable) begincpu_clock_cycles <= cpu_clock_cycles + 1;if (instruction_valid_in) beginnum_instructions <= num_instructions + 1 + fast_jump_in;if (instruction_in[`IL] == 2) num_instructions_2size <= num_instructions_2size + 1;if (instruction_in[`IL] == 3) num_instructions_3size <= num_instructions_3size + 1;if (vector_in) beginnum_instructions_vector <= num_instructions_vector + 1;end else beginnum_instructions_gp <= num_instructions_gp + 1;if (mask_off) num_instructions_gp_mask0 <= num_instructions_gp_mask0 + 1;endif (category_in == `CAT_JUMP) begin // jump instructionsnum_jump_call_return <= num_jump_call_return + 1 + fast_jump_in;if (opj_in <= `IJ_LAST_CONDITIONAL) num_jump_conditional <= num_jump_conditional + 1;else num_jump_call_indirect <= num_jump_call_indirect + 1;endendif (fast_jump_in) begin // fast jump/call/return bypassing pipelinenum_jump_call_direct <= num_jump_call_direct + 1;if (!(instruction_valid_in && category_in == `CAT_JUMP)) beginnum_jump_call_return <= num_jump_call_return + 1; // count also total jumps, except if counted aboveendend// reset countersif (reset_cpu_clock_cycles | reset) begincpu_clock_cycles <= 0;endif (reset_num_instructions | reset) beginnum_instructions <= 0;num_instructions_2size <= 0;num_instructions_3size <= 0;num_instructions_gp <= 0;num_instructions_gp_mask0 <= 0;endif (reset_num_instructions_vector | reset) beginnum_instructions_vector <= 0;endif (reset_num_instructions_jump | reset) beginnum_jump_call_return <= 0; // count control transfer instructionsnum_jump_call_direct <= 0; // count direct unconditional jumps and callsnum_jump_call_indirect <= 0; // count indirect jumps and callsnum_jump_conditional <= 0; // count conditional jumpsendend// Error detection. This is not controlled by clock enable because clock enable may stop when error is detectedalways_ff @(posedge clock) beginerror_last <= |errors_detect_in; // error detected in last clock cycleclock_enabled_last <= clock_enable; // clock was enabled in last clock cycle. new instruction encountered// A new error is detected if there was no error signal in the last clock cycle// of if clock_enable has allowed the execution of a new instructionif (|errors_detect_in && (clock_enabled_last || !error_last)) begin// a new error is detected. count it only onceif (errors_detect_in[0]) num_unknown_instruction <= num_unknown_instruction + 1;else if (errors_detect_in[1]) num_wrong_operands <= num_wrong_operands + 1;else if (errors_detect_in[2]) num_array_overflow <= num_array_overflow + 1;else if (errors_detect_in[3]) num_read_violation <= num_read_violation + 1;else if (errors_detect_in[4]) num_write_violation <= num_write_violation + 1;else if (errors_detect_in[5]) num_misaligned_memory <= num_misaligned_memory + 1;end// remember first errorif (|errors_detect_in) beginif (!first_error_saved) beginif (errors_detect_in[0]) beginfirst_error <= 1;first_error_address <= alu_instruction_pointer;end else if (errors_detect_in[1]) beginfirst_error <= 2;if (call_stack_overflow) first_error_address <= fetch_instruction_pointer;else first_error_address <= alu_instruction_pointer;end else if (errors_detect_in[2]) beginfirst_error <= 3;first_error_address <= dataread_instruction_pointer;end else if (errors_detect_in[3]) beginfirst_error <= 4;first_error_address <= dataread_instruction_pointer;end else if (errors_detect_in[4]) beginfirst_error <= 5;first_error_address <= dataread_instruction_pointer;end else if (errors_detect_in[5]) beginfirst_error <= 6;first_error_address <= dataread_instruction_pointer;endendfirst_error_saved <= 1;endif (reset_num_errors | reset) begin// reset error countersnum_unknown_instruction <= 0; // count unknown instructionnum_wrong_operands <= 0; // count wrong operands for instructionsnum_array_overflow <= 0; // count array index out of rangenum_read_violation <= 0; // count memory read access violationnum_write_violation <= 0; // count memory write access violationnum_misaligned_memory <= 0; // count misaligned memory accessfirst_error <= 0;first_error_address <= 0;first_error_saved <= 0;endif (clear_error_in) beginfirst_error_saved <= 0; // debugger clear errorend// reconstruct alu_instruction_pointer:if (clock_enable & dataread_valid) beginalu_instruction_pointer <= dataread_instruction_pointer;endend// implement uart receiverUART_RX UART_RX_inst (.reset(reset | fifo_buffer_input_reset | fifo_buffer_input_reset_error), // reset.clock(clock), // clock at `CLOCK_RATE.rx_in(uart_bit_in), // RX input.receive_complete_out(UART_RX_receive_complete), // byte received. Will be high for 1 clock cycle after the middle of the stop bit.error_out(UART_RX_error), // transmission error. Remains high until reset in case of error.byte_out(UART_RX_byte_out) // byte output);// implement uart transmitterUART_TX UART_TX_inst (.reset(reset | fifo_buffer_output_reset | fifo_buffer_output_reset_error), // reset.clock(clock), // clock at `CLOCK_RATE.start_in(fifo_buffer_output_ready), // command to send one byte.byte_in(fifo_buffer_output_byte), // byte input.active_out(UART_TX_active), // is busy.tx_out(uart_bit_out), // TX output.done_out(UART_TX_done) // will be high for one clock cycle shortly before the end of the stop bit);// implement fifo buffer for receiverfifo_buffer #(.size_log2(`IN_BUFFER_SIZE_LOG2))fifo_buffer_input (.reset(reset | fifo_buffer_input_reset), // reset everything.reset_error(reset | fifo_buffer_input_reset_error), // clear error flags.clock(clock), // clock at `CLOCK_RATE.read_next(fifo_buffer_input_read_next & clock_enable),// read next byte from buffer.write(UART_RX_receive_complete), // write one byte to buffer.byte_in(UART_RX_byte_out), // serial byte input.byte_out(fifo_buffer_input_byte), // serial byte output prefetched.data_ready_out(fifo_buffer_input_ready), // the buffer contains at least one byte.overflow(fifo_buffer_input_overflow), // attempt to write to full buffer.underflow(fifo_buffer_output_underflow), // attempt to read from empty buffer.num(fifo_buffer_input_num) // number of bytes currently in buffer);// implement fifo buffer for transmitterfifo_buffer #(.size_log2(`OUT_BUFFER_SIZE_LOG2))fifo_buffer_output (.reset(reset | fifo_buffer_output_reset), // reset everything.reset_error(reset | fifo_buffer_output_reset_error), // clear error flags.clock(clock), // clock at `CLOCK_RATE.read_next(UART_TX_done), // read next byte from buffer.write(fifo_buffer_output_write & clock_enable), // write one byte to buffer.byte_in(serial_output_byte_in), // serial byte input.byte_out(fifo_buffer_output_byte), // serial byte output prefetched.data_ready_out(fifo_buffer_output_ready), // the buffer contains at least one byte.overflow(fifo_buffer_output_overflow), // attempt to write to full buffer.underflow(fifo_buffer_output_underflow), // attempt to read from empty buffer.num(fifo_buffer_output_num) // number of bytes currently in buffer);endmodule
Go to most recent revision | Compare with Previous | Blame | View Log
