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

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [top.sv] - Rev 123

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

/******************************************************************************
* Engineer: Agner Fog 
* 
* Create date:   2020-05-03
* Last modified: 2021-08-05
* Module name:   top
* Project name:  ForwardCom soft core
* Tool versions: Vivado 2020.1 
* License:       CERN-OHL-W version 2 or later
* Description:   Top level module of ForwardCom softcore
* 
* The pipeline stages are connected here:
* 1.  fetch:            Fetch code words from code memory
* 2.  decoder           Decode instruction code
* 3.  register_read     Read registers. The register file is included in this stage
* 4.  addressgenerator  Calculate address of any memory operand
* 5.  dataread          Wait for data being read from data RAM
* 6a. alu               Execute the instruction and calculate the result
* 6b. in_out_ports      Input and output instructions etc. go here instead of into alu
*
* Other modules connected here:
* clock_generator:      Controls the clock frequency of the global clock
* code_memory:          Code memory or cache
* data_memory:          Data memory or cache
* call_stack:           Call stack for function return addresses
* debug_display:        Shows contents of each pipeline stage on LCD display
* debugger.vh:          Displays values of any signals anywhere in system on LED displays
*
******************************************************************************/
`include "defines.vh"

/* 
Signals have name prefixes indicating the modules that generate them.
Handshaking signals between pipeline stages:
valid_in:                  Preceding stage has valid data ready
valid_out:                 Valid data are ready for next stage
stall_in:                  Keep your data for the next clock cycle
stall_out:                 Unable to receive new data
stall_predict_out:         Predict that the next stage in pipeline will stall in next clock cycle
There is currently no contention for result buses, but future implementation may need handshaking for this:
result_bus_require_out:    Needs result bus in next clock cycle
result_bus_acknowledge_in: No unit with higher privilege is taking the result bus
result_bus_enable_out:     A result is on the result bus
*/

module top (
    input clock100,               // board input clock 100 MHz
    input switch0,                // switches for debug modes
    input switch1,                // switches for debug modes
    input switch2,                // switches for debug modes
    input switch3,                // switches for debug modes
    input switch4,                // switches for debug modes
    input switch5,                // switches for debug modes
    input switch6,                // switches for debug modes
    input switch7,                // switches for debug modes
    input switch8,                // switches for debug modes
    input switch15,               // disables error stop

    input step_button,            // Single stepping (RIGHT BUTTON)  
    input run_button,             // Stop single stepping and start free running (UP BUTTON)  
    input reset_button,           // Reset to start of program (DOWN BUTTON)
    input load_button,            // Load program throung serial interfase (!CPU RESET BUTTON)
      
    input step_button_x,          // Single stepping (external button)  
    input run_button_x,           // Stop single stepping and start free running (external button)  
    input reset_button_x,         // Reset to start of program (external button)
    input load_button_x,          // Loader (external button)
    input external_connected_x,   // high if external debug interface is connected
    
    input debug1_switch,          // enable single-stepping, pipeline mode
    input debug2_switch,          // enable single-stepping, instruction mode
    input uart_txd_in,            // UART transmit from PC
    input uart_rts_in,            // UART RTS from PC
    output reg [7:0] segment7seg, // segment output, active low
    output reg [7:0] digit7seg,   // digit select output, active low
    output reg [3:0] lcd_data,    // data to LCD display
    output reg lcd_rs,            // control signal for LCD display
    output reg [1:0] lcd_e,       // enable signals for LCD displays    
    output uart_rxd_out,          // UART receive to PC
    output uart_cts_out,          // UART CTS to PC
    output  led0,                 // use of led's: see below
    output  led1,
    output  led2,
    output  led3, 
    output  led4, 
    output  led5, 
    output  led6, 
    output  led7, 
    output  led12, 
    output  led13, 
    output  led14, 
    output  led15,
    output  led16R,               // RGB led
    output  led16G,
    output  led16B
);


// generate clock (Xilinx specific. Generated by Clocking Wizard)
clock_generator clock_generator_inst (
    .clk_in(clock100),            // board input clock, 100 MHz
    .clk_out(clock),              // synthesized clock, frequency is `CLOCK_FREQUENCY
    .locked()                     // clock frequency has stabilized
);

// control single stepping
reg single_step_mode;
reg step_button_debounced;
reg run_button_debounced;
reg reset_button_debounced;
reg load_button_debounced;
reg step_button_pulse;
reg run_button_pulse;
reg reset_button_pulse;
reg load_button_pulse;

reg [2:0] reset_step = 3'b111;    // shift register for system reset clock cycles
reg clock_enable = 0;
reg system_reset = 1;             // reset everything. load program
reg program_restart = 0;          // restart loaded program


// pushbutton debouncers
// on-board buttons are always enabled, external buttons are enabled by external_connected_x
logic[3:0] input_buttons;
logic[3:0] debounced_buttons;
logic[3:0] button_pulse;

assign input_buttons[0] = step_button  | (step_button_x & external_connected_x);
assign input_buttons[1] = run_button   | (run_button_x & external_connected_x);
assign input_buttons[2] = reset_button | (reset_button_x & external_connected_x);
assign input_buttons[3] = (~load_button) | (load_button_x & external_connected_x);
assign debounced_buttons[0] = step_button_debounced;
assign debounced_buttons[1] = run_button_debounced;
assign debounced_buttons[2] = reset_button_debounced;
assign debounced_buttons[3] = load_button_debounced;
assign button_pulse[0] = step_button_pulse;
assign button_pulse[1] = run_button_pulse;
assign button_pulse[2] = reset_button_pulse;
assign button_pulse[3] = load_button_pulse;

debounce #(.num(4) ) debounce_inst
(.clock(clock), 
.buttons_in (input_buttons),
.buttons_out(debounced_buttons),
.pulse_out(button_pulse));



/***************************************************
       Signals connecting the stages
***************************************************/

// code memory
logic [`CODE_DATA_WIDTH-1:0] code_memory_data;              // Data out
logic [31:0]                 code_memory_debug;

// data memory
logic [`RB1:0] data_memory_data;

// call stack
logic [`CODE_ADDR_WIDTH-1:0] call_stack_pop_data;          // return address popped from call stack
logic call_stack_overflow;                                 // call stack overflow or underflow or error

// register file input
logic  [5:0]   debug_reada;                                // read port for debugger

// signals from each pipeline stage

// fetch stage
logic fetch_valid;
logic fetch_jump;                                          // jump instruction bypassing pipeline
logic fetch_call_e;                                        // executing call instruction
logic fetch_return_e;                                      // executing return instruction
logic [95:0] fetch_instruction;
logic [`CODE_ADDR_WIDTH-1:0] fetch_instruction_pointer;    // point to current instruction
logic                        fetch_read_enable;
logic [`CODE_ADDR_WIDTH-2:0] fetch_read_addr;              // Address for reading from code ram
logic [`CODE_ADDR_WIDTH-1:0] fetch_call_push_data;         // return address pushed to call stack
logic [31:0]                 fetch_debug1;                 // temporary debug output

// decoder
logic [`TAG_WIDTH-1:0] decoder_tag_val;                    // instruction tag value
logic        decoder_tag_write;                            // tag write enable
logic        decoder_read;                                 // read register enable
logic        decoder_valid;                                // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] decoder_instruction_pointer;  // address of current instruction
logic [95:0] decoder_instruction;                          // first word of instruction    
logic        decoder_stall;                                // Not ready to receive next instruction
logic [5:0]  decoder_tag_a;                                // register number for instruction tag
logic        decoder_vector;                               // this is a vector instruction
logic [1:0]  decoder_category;                             // 00: multiformat, 01: single format, 10: jump
logic [1:0]  decoder_format;                               // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [2:0]  decoder_rs_status;                            // use of RS
logic [2:0]  decoder_rt_status;                            // use of RT
logic [1:0]  decoder_ru_status;                            // 1: RU is used
logic [1:0]  decoder_rd_status;                            // 1: RD is used as input
logic [1:0]  decoder_mask_status;                          // what the mask register is used for
logic        decoder_mask_options;                         // 1: mask register may contain options    
logic        decoder_mask_alternative;                     // mask register and fallback register used for alternative purposes
logic [2:0]  decoder_fallback_use;                         // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT    
logic [1:0]  decoder_num_operands;                         // number of source operands
logic [1:0]  decoder_result_type;                          // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0]  decoder_offset_field;                         // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
logic [1:0]  decoder_immediate_field;                      // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0]  decoder_scale_factor;                         // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic        decoder_index_limit;                          // index has a limit
logic [31:0] decoder_debug1;                               // temporary debug output

// register read stage
logic         registerread_valid;                          // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] registerread_instruction_pointer; // address of current instruction
logic [95:0]  registerread_instruction;                    // first word of instruction    
logic         registerread_stall_predict;                  // predict next stage will stall
logic [`TAG_WIDTH-1:0] registerread_tag_val;               // instruction tag value
logic         registerread_vector;                         // this is a vector instruction
logic [1:0]   registerread_category;                       // 00: multiformat, 01: single format, 10: jump
logic [1:0]   registerread_format;                         // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [1:0]   registerread_num_operands;                   // number of source operands
logic [1:0]   registerread_result_type;                    // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0]   registerread_offset_field;                   // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
logic [1:0]   registerread_immediate_field;                // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0]   registerread_scale_factor;                   // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic         registerread_index_limit;                    // The field indicated by offset_field contains a limit to the index
logic [`RB:0] registerread_rd_val;                         // value of register operand RD, bit `RB indicates missing 
logic [`RB:0] registerread_rs_val;                         // value of register operand RS, bit `RB indicates missing 
logic [`RB:0] registerread_rt_val;                         // value of register operand RT, bit `RB indicates missing 
logic [`RB:0] registerread_ru_val;                         // value of register operand RU, bit `RB indicates missing 
logic [`MASKSZ:0] registerread_regmask_val;                // value of mask register, bit 32 indicates missing
logic [1:0]   registerread_rd_status;                      // RD is used as input
logic [2:0]   registerread_rs_status;                      // use of RS
logic [2:0]   registerread_rt_status;                      // use of RT
logic [1:0]   registerread_ru_status;                      // RU is used
logic [1:0]   registerread_mask_status;                    // mask register is used
logic         registerread_mask_alternative;               // mask register and fallback register used for alternative purposes
logic [2:0]   registerread_fallback_use;                   // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT    
logic [32:0]  registerread_debugport;                      // register read by debugger

// address generator
logic [`COMMON_ADDR_WIDTH-1:0] addrgen_read_write_address; // address of memory operand
logic        addrgen_read_enable;                          // read from data memory
logic [1:0]  addrgen_read_data_size;
logic [7:0]  addrgen_write_enable;
logic [63:0] addrgen_write_data;                           // Any part of the 64 bits write bus can be used when the operand size is less than 64 bits 
logic        addrgen_valid;                                // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] addrgen_instruction_pointer;  // address of current instruction
logic [63:0] addrgen_instruction;                          // first word of instruction    
logic        addrgen_stall_next;                           // address generator waiting for an operand
logic [`TAG_WIDTH-1:0] addrgen_tag_val;                    // instruction tag value
logic [`RB:0] addrgen_operand1;                            // value of first register operand 
logic [`RB:0] addrgen_operand2;                            // value of second register operand 
logic [`RB:0] addrgen_operand3;                            // value of last operand 
logic [`MASKSZ:0] addrgen_regmask_val;                     // value of mask register, bit 32 indicates valid
logic        addrgen_vector;                               // this is a vector instruction
logic [1:0]  addrgen_category;                             // instruction category: multiformat, single format, jump
logic [1:0]  addrgen_format;                               // instruction format: A, E, B, D
logic        addrgen_mask_status;                          // mask register is used    
logic        addrgen_mask_alternative;                     // mask register and fallback register used for alternative purposes
logic [2:0]  addrgen_fallback_use;                         // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
logic [1:0]  addrgen_num_operands;                         // number of source operands
logic [1:0]  addrgen_result_type;                          // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0]  addrgen_offset_field;                         // unused
logic [1:0]  addrgen_immediate_field;                      // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0]  addrgen_scale_factor;                         // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic        addrgen_memory_operand;                       // The instruction has a memory operand
logic        addrgen_array_error;                          // Array index exceeds limit

logic [31:0] addrgen_debug1;                               // temporary debug output
logic [31:0] addrgen_debug2;                               // temporary debug output
logic [31:0] addrgen_debug3;                               // temporary debug output

// data read stage
logic        dataread_valid;                               // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] dataread_instruction_pointer; // address of current instruction
logic [31:0] dataread_instruction;                         // first word of instruction    
logic        dataread_stall_predict;                       // predict next stage will stall
logic [`TAG_WIDTH-1:0] dataread_tag_val;                   // instruction tag value
logic [`RB:0] dataread_operand1;                           // value of first operand 
logic [`RB:0] dataread_operand2;                           // value of second operand 
logic [`RB:0] dataread_operand3;                           // value of last operand 
logic [`MASKSZ:0] dataread_mask_val;                       // value of mask, bit 32 is 0 if valid
logic        dataread_opr2_from_ram;                       // value of operand 2 comes from data memory
logic        dataread_opr3_from_ram;                       // value of last operand comes from data memory
logic        dataread_vector;                              // this is a vector instruction
logic [1:0]  dataread_category;                            // 00: multiformat, 01: single format, 10: jump
logic [1:0]  dataread_format;                              // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [1:0]  dataread_num_operands;                        // number of source operands
logic        dataread_opr1_used;                           // opr1_val_out is needed
logic        dataread_opr2_used;                           // opr2_val_out is needed
logic        dataread_opr3_used;                           // opr3_val_out is needed
logic        dataread_regmask_used;                        // regmask_val_out is needed
logic        dataread_mask_alternative;                    // mask register and fallback register used for alternative purposes
logic [1:0]  dataread_result_type;                         // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [3:0]  dataread_exe_unit;                            // each bit enables a particular execution unit
                                                           // 1: ALU, 10: MUL, 100: DIV, 1000: IN/OUT
logic [6:0]  dataread_opx;                                 // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
logic [5:0]  dataread_opj;                                 // operation ID for conditional jump instructions
logic [2:0]  dataread_ot;                                  // operand type
logic [5:0]  dataread_option_bits;                         // option bits from IM3 or mask
logic [15:0] dataread_im2_bits;                            // constant bits from IM2 as extra operand    
logic        dataread_trap;                                // trap instruction detected. enable single step mode
logic        dataread_array_error;                         // array index out of bounds
logic        dataread_read_address_error;                  // invalid read memory address
logic        dataread_write_address_error;                 // invalid write memory address 
logic        dataread_misaligned_address_error;            // misaligned read/write memory address     
logic [31:0] dataread_debug;                               // output for debugging 

// alu stage
logic        alu_valid;                                    // for debug display: alu is active
logic        alu_write_en;                                 // write value to register file
logic [5:0]  alu_register_a;                               // register to write
logic [`RB1:0] alu_result;                                 // result to write
logic [`TAG_WIDTH-1:0] alu_tag;                            // instruction tag value
logic        alu_jump;                                     //  jump instruction: jump taken
logic        alu_nojump;                                   // jump instruction: jump not taken
logic [`CODE_ADDR_WIDTH-1:0] alu_jump_pointer;             // jump target to fetch unit
logic alu_stall;
logic alu_stall_next;
logic alu_error;                                           // unknown instruction
logic alu_error_parm;                                      // wrong parameter for instruction
logic [31:0] alu_debug1;                                   // output for debugger
logic [31:0] alu_debug2;                                   // output for debugger

// mul/div alu
logic        muldiv_valid;                                 // for debug display: alu is active
logic        muldiv_write_en;                              // write value to register file
logic [4:0]  muldiv_register_a;                            // register to write
logic [`RB1:0] muldiv_result;                              // result to write
logic [`TAG_WIDTH-1:0] muldiv_tag;                         // instruction tag value
logic muldiv_stall;
logic muldiv_stall_next;
logic muldiv_error;                                        // unknown instruction
logic muldiv_error_parm;                                   // wrong parameter for instruction
logic [31:0] muldiv_debug1;                                // output for debugger
logic [31:0] muldiv_debug2;                                // output for debugger

// in_out_ports
logic inout_valid;                                         // for debug display: in_out is active
logic inout_write_en;                                      // write value to register file
logic [5:0] inout_register_a;                              // register to write
logic [`RB1:0] inout_result;                               // result to write
logic [`TAG_WIDTH-1:0] inout_tag;                          // instruction tag value
logic inout_nojump;                                        // serializing instruction read_perf gives jump not taken signal to resume pipeline
logic inout_stall;
logic inout_stall_next;
logic inout_error;                                         // unknown instruction
logic inout_error_parm;                                    // wrong parameter for instruction
logic [`N_ERROR_TYPES-1:0] inout_capab_disable_errors;     // capab2 register: disable errors
logic [3:0] inout_first_error;                             // error type for first error, stored in inout module
logic [`CODE_ADDR_WIDTH-1:0] inout_first_error_address;    // code address of first error
logic [31:0] inout_debug;                                  // output for debugger

// error handling
logic [`N_ERROR_TYPES-1:0] errors_detect;                  // one bit for each type of error detected
logic clear_error;                                         // clear error on debug display
reg   show_error;                                          // show error on debug display


/***************************************************
       Top level logic signals
***************************************************/
// result bus 1
logic bus1_write_en;                                       // write value to register file
logic [5:0] bus1_register_a;                               // register to write (includes system registers)
logic [`RB1:0] bus1_value;                                 // value to write
logic [`TAG_WIDTH-1:0] bus1_tag;                           // result tag for value on bus 1

// result bus 2
logic bus2_write_en;                                       // write value to register file
logic [4:0] bus2_register_a;                               // register to write
logic [`RB1:0] bus2_value;                                 // value to write
logic [`TAG_WIDTH-1:0] bus2_tag;                           // result tag for value on bus 2

// signals for predicting when a result will be available
logic [`TAG_WIDTH-1:0] predict_tag1;                       // result tag value on bus 1 in next clock cycle
logic [`TAG_WIDTH-1:0] predict_tag2;                       // result tag value on bus 2 in next clock cycle

logic [`CODE_ADDR_WIDTH-2:0] code_read_addr;               // Address for reading from ram

reg [2:0] color_led16;                                     // RGB led

always_comb begin
    // result bus 1
    // There are no tri-state buffers inside the FPGA so we have to simulate the buses by OR'ing results:
    bus1_write_en  = alu_write_en | inout_write_en;        // write value to register file
    bus1_register_a = alu_register_a | inout_register_a;   // register to write
    bus1_value = alu_result | inout_result;                // value to write
    bus1_tag = alu_tag | inout_tag;                        // tag for result on bus 1

    // result bus 2 not yet used
    bus2_write_en  = muldiv_write_en;                      // write value to register file
    bus2_register_a = muldiv_register_a;                   // register to write
    bus2_value = muldiv_result;                            // value to write
    bus2_tag = muldiv_tag;                                 // tag for result on bus 2

    // read address for code memory. comes from fetch unit, except for taken conditional or indirect jumps/calls 
    code_read_addr = alu_jump ? (alu_jump_pointer >> 1) : fetch_read_addr;
    // predict next tag on bus 1
    predict_tag1 = (dataread_exe_unit[0] | dataread_exe_unit[3]) ? dataread_tag_val : 0;
    // predict next tag on bus 2. To do: insert propagation delay !! 
    predict_tag2 = (dataread_exe_unit[1] | dataread_exe_unit[2]) ? dataread_tag_val : 0; 
    
    // error detection
    errors_detect[0] = alu_error | muldiv_error | inout_error; // unknown instruction 
    errors_detect[1] = alu_error_parm | muldiv_error_parm | inout_error_parm | call_stack_overflow; // wrong parameter for instruction
    errors_detect[2] = dataread_array_error;               // array index out of bounds
    errors_detect[3] = dataread_read_address_error;        // read address violation
    errors_detect[4] = dataread_write_address_error;       // write address violation
    errors_detect[5] = dataread_misaligned_address_error;  // misaligned memory address
    clear_error = reset_button_debounced | step_button_pulse | run_button_pulse | load_button_debounced; // clear error on debug display

end

// single step and reset control
always_ff @(posedge clock) begin 
    reset_step[2:0] <= {reset_step[1:0],(reset_button_debounced|load_button_debounced)}; // shift register delaying reset button
    if (reset_button_debounced) begin
        clock_enable <= 1;                                 // enable clock while resetting
        system_reset <= 1;                                 // reset everything for 3 clock cycles
        program_restart <= 1;
        single_step_mode <= 0;
    end else if (load_button_debounced) begin
        clock_enable <= 1;                                 // enable clock while resetting
        system_reset <= 1;                                 // reset everything for 3 clock cycles
        program_restart <= 0;        
        single_step_mode <= 0;
    end else if (reset_step != 0) begin
        clock_enable <= 1;                                 // enable clock while resetting
        system_reset <= 1;                                 // reset everything for 3 clock cycles
        single_step_mode <= 0;                             // start in single step mode
    end else if (single_step_mode) begin                   // single-stepping for debugging
        clock_enable <= step_button_pulse;                 // enable for one clock cycle
        system_reset <= 0;
        program_restart <= 0;
    end else begin                                         // not single_step_mode
        clock_enable <= 1;
        system_reset <= 0;
        program_restart <= 0;
    end
    
    // set or clear single step mode
    if (run_button_pulse)  single_step_mode <= 0;
    if (step_button_pulse) single_step_mode <= 1;
    if (dataread_trap)     single_step_mode <= 1;          // breakpoint sets single step mode
    if (|(errors_detect & ~inout_capab_disable_errors) && !switch15) single_step_mode <= 1; // error detected
    
    if (clear_error) show_error <= 0;
    if (|(errors_detect & ~inout_capab_disable_errors)) show_error <= 1;
end


/***************************************************
       Memory modules
***************************************************/

// code memory
code_memory code_memory_inst(
    .clock(clock),                                         // clock
    .clock_enable(clock_enable),
    .read_enable(fetch_read_enable | alu_jump),            // read enable
    .write_enable(addrgen_write_enable),
    .write_addr_in(addrgen_read_write_address),
    .write_data_in(addrgen_write_data),                    // Data in
    .read_addr_in(code_read_addr),                         // Address for reading from code ram
    .data_out(code_memory_data),                           // Data out
    .debug_out(code_memory_debug)
);
    
    
// read/write data memory
data_memory data_memory_inst (
    .clock(clock),                                         // clock
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .read_write_addr(addrgen_read_write_address),          // Address for reading from ram
    .read_enable(addrgen_read_enable),                     // read enable
    .read_data_size(addrgen_read_data_size),
    .write_enable(addrgen_write_enable),                   // write enable for each byte separately
    .write_data_in(addrgen_write_data), 
    .read_data_out(data_memory_data)                       // Data out
);

// call stack
call_stack call_stack_instance(
    .clock(clock),                                         // clock
    .clock_enable(clock_enable),                           // clock enable
    .reset(system_reset),                                  // reset
    .call_e(fetch_call_e),                                 // Executing call instruction
    .return_e(fetch_return_e),                             // Executing return instruction
    .push_data(fetch_call_push_data),                      // Return address pushed at call instruction
    .pop_data(call_stack_pop_data),                        // Return address popped at return instruction
    .overflow(call_stack_overflow));                       // stack overflow or underflow or error

    
/***************************************************
       Pipeline stages
***************************************************/

// code fetch module
fetch fetch_inst(
    .clock(clock),                                         // system clock (100 MHz)
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset.
    .restart(program_restart),                             // restart loaded program
    .valid_in(1),                                          // data from code memory ready
    .stall_in(registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next),   // pipeline is stalled 
    .jump_in(alu_jump),                                    // a jump target is coming from the ALU.
    .nojump_in(alu_nojump | inout_nojump),                 // jump target is next instruction
    .jump_pointer(alu_jump_pointer),                       // jump target from ALU. jump_pointer is also sent to the code memory
    .read_data(code_memory_data),                          // data from code memory
    .return_pop_data(call_stack_pop_data),                 // Return address popped here at return instruction
    .read_addr_out(fetch_read_addr),                       // code read address relative to code memory start
    .read_enable_out(fetch_read_enable),                   // code memory read enable
    .valid_out(fetch_valid),                               // An instruction is ready for output to decoder
    .jump_out(fetch_jump),                                 // Jump instruction bypassing pipeline
    .instruction_pointer_out(fetch_instruction_pointer),   // address of current instruction
    .instruction_out(fetch_instruction),                   // current instruction, up to 3 32-bit words long
    .call_e_out(fetch_call_e),                             // Executing call instruction. push_data contains return address
    .return_e_out(fetch_return_e),                         // Executing return instruction. return address is available in advance on pop_data
    .stall_predict_out(),                                  // predict stall in decoder
    .call_push_data_out(fetch_call_push_data) ,            // Return address pushed here at call instruction
    .debug1_out(fetch_debug1)                              // temporary debug output
);

decoder decoder_inst (
    .clock(clock),                                         // system clock (100 MHz)
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset. 
    .valid_in(fetch_valid),                                // data from fetch module ready
    .stall_in(registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next),   // pipeline is stalled
    .instruction_pointer_in(fetch_inst.instruction_pointer_out), // address of current instruction
    .instruction_in(fetch_instruction),                    // current instruction, up to 3 words long
    .write_en1(bus1_write_en),                             // a result is written to bus 1
    .write_tag1(bus1_tag),                                 // tag of result in bus 1
    .write_en2(bus2_write_en),                             // a result is written to bus 2
    .write_tag2(bus2_tag),                                 // tag of result in bus 2
        
    .valid_out(decoder_valid),                             // An instruction is ready for output to next stage
    .instruction_pointer_out(decoder_instruction_pointer), // address of current instruction
    .instruction_out(decoder_instruction),                 // first word of instruction    
    .stall_out(decoder_stall),                             // Not ready to receive next instruction
    .tag_a_out(decoder_tag_a),                             // register number for instruction tag
    .tag_val_out(decoder_tag_val),                         // instruction tag value
    .tag_write_out(decoder_tag_write),                     // instruction tag write enable
    .vector_out(decoder_vector),                           // this is a vector instruction
    .category_out(decoder_category),                       // 00: multiformat, 01: single format, 10: jump
    .format_out(decoder_format),                           // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
    .rs_status_out(decoder_rs_status),                     // use of RS
    .rt_status_out(decoder_rt_status),                     // use of RT
    .ru_status_out(decoder_ru_status),                     // 1: RU is used
    .rd_status_out(decoder_rd_status),                     // 1: RD is used as input
    .mask_status_out(decoder_mask_status),                 // What the mask register is used for
    .mask_options_out(decoder_mask_options),               // 1: mask register may contain options
    .mask_alternative_out(decoder_mask_alternative),       // mask register and fallback register used for alternative purposes
    .fallback_use_out(decoder_fallback_use),               // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
    .num_operands_out(decoder_num_operands),               // number of source operands
    .result_type_out(decoder_result_type),                 // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing 
    .offset_field_out(decoder_offset_field),               // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
    .immediate_field_out(decoder_immediate_field),         // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit    
    .scale_factor_out(decoder_scale_factor),               // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
    .index_limit_out(decoder_index_limit),                 // The field indicated by offset_field contains a limit to the index
    .debug1_out(decoder_debug1)                            // temporary debug output
);

register_read register_read_inst (
    .clock(clock),                                         // system clock
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset. 
    .valid_in(decoder_valid),                              // data from fetch module ready
    .stall_in(registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next),   // pipeline is stalled
    .instruction_pointer_in(decoder_instruction_pointer),  // address of current instruction
    .instruction_in(decoder_instruction),                  // current instruction, up to 3 words long
    .tag_write_in(decoder_tag_write),                      // write tag
    .tag_val_in(decoder_tag_val),                          // instruction tag value    
    .vector_in(decoder_vector),                            // this is a vector instruction
    .category_in(decoder_category),                        // 00: multiformat, 01: single format, 10: jump
    .format_in(decoder_format),                            // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)   
    .rs_status_in(decoder_rs_status),                      // 1: RS is register operand
    .rt_status_in(decoder_rt_status),                      // 1: RT is register operand
    .ru_status_in(decoder_ru_status),                      // 1: RU is used
    .rd_status_in(decoder_rd_status),                      // 1: RD is used as input
    .mask_status_in(decoder_mask_status),                  // use of mask
    .mask_options_in(decoder_mask_options),                // 1: mask register may contain options   
    .mask_alternative_in(decoder_mask_alternative),        // mask register and fallback register used for alternative purposes
    .fallback_use_in(decoder_fallback_use),                // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
    .num_operands_in(decoder_num_operands),                // number of source operands
    .result_type_in(decoder_result_type),                  // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .offset_field_in(decoder_offset_field),                // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
    .immediate_field_in(decoder_immediate_field),          // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
    .scale_factor_in(decoder_scale_factor),                // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
    .index_limit_in(decoder_index_limit),                  // The field indicated by offset_field contains a limit to the index
    .writeport1(bus1_value),                               // result bus 1
    .writea1(bus1_register_a),                             // address input for bus 1
    .write_en1(bus1_write_en),                             // a result is written to bus 1
    .write_tag1(bus1_tag),                                 // tag of result in bus 1
    .writeport2(bus2_value),                               // result bus 2
    .writea2(bus2_register_a),                             // address input for bus 2
    .write_en2(bus2_write_en),                             // a result is written to bus 2
    .write_tag2(bus2_tag),                                 // tag of result in bus 2
    .debug_reada(debug_reada),                             // register read port for debugger        
    
    .valid_out(registerread_valid),                        // An instruction is ready for output to next stage
    .instruction_pointer_out(registerread_instruction_pointer), // address of current instruction
    .instruction_out(registerread_instruction),            // first word of instruction    
    .stall_predict_out(registerread_stall_predict),        // predict next stage will stall    
    .tag_val_out(registerread_tag_val),                    // instruction tag value
    .vector_out(registerread_vector),                      // this is a vector instruction
    .category_out(registerread_category),                  // 00: multiformat, 01: single format, 10: jump
    .format_out(registerread_format),                      // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
    .num_operands_out(registerread_num_operands),          // number of source operands    
    .result_type_out(registerread_result_type),            // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .offset_field_out(registerread_offset_field),          // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
    .immediate_field_out(registerread_immediate_field),    // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit    
    .scale_factor_out(registerread_scale_factor),          // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
    .index_limit_out(registerread_index_limit),            // The field indicated by offset_field contains a limit to the index    
    .rd_val_out(registerread_rd_val),                      // value of register operand RD, bit `RB indicates missing 
    .rs_val_out(registerread_rs_val),                      // value of register operand RS, bit `RB indicates missing 
    .rt_val_out(registerread_rt_val),                      // value of register operand RT, bit `RB indicates missing 
    .ru_val_out(registerread_ru_val),                      // value of register operand RU, bit `RB indicates missing 
    .regmask_val_out(registerread_regmask_val),            // value of mask register, bit 32 indicates missing
    .rd_status_out(registerread_rd_status),                // 1: RD is used as input
    .rs_status_out(registerread_rs_status),                // use of RS
    .rt_status_out(registerread_rt_status),                // use of RT
    .ru_status_out(registerread_ru_status),                // 1: RU is used
    .mask_status_out(registerread_mask_status),            // 1: mask register is used
    .mask_alternative_out(registerread_mask_alternative),  // mask register and fallback register used for alternative purposes
    .fallback_use_out(registerread_fallback_use),          // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
    .debugport_out(registerread_debugport)                 // read for debugging purpose 
);

addressgenerator addressgenerator_inst (
    .clock(clock),                                         // system clock (100 MHz)
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset. 
    .valid_in(registerread_valid),                         // data from fetch module ready
    .stall_in(dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next),   // pipeline is stalled
    .instruction_pointer_in(registerread_instruction_pointer), // address of current instruction
    .instruction_in(registerread_instruction),             // current instruction, up to 3 words long       
    .tag_val_in(registerread_tag_val),                     // instruction tag value    
    .vector_in(registerread_vector),                       // this is a vector instruction
    .category_in(registerread_category),                   // 00: multiformat, 01: single format, 10: jump
    .format_in(registerread_format),                       // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)    
    .rs_status_in(registerread_rs_status),                 // use of RS
    .rt_status_in(registerread_rt_status),                 // use of RT
    .ru_status_in(registerread_ru_status),                 // RU is used
    .rd_status_in(registerread_rd_status),                 // RD is used as input
    .mask_status_in(registerread_mask_status),             // mask register used
    .mask_alternative_in(registerread_mask_alternative),   // mask register and fallback register used for alternative purposes
    .fallback_use_in(registerread_fallback_use),           // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
    .num_operands_in(registerread_num_operands),           // number of source operands
    .result_type_in(registerread_result_type),             // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .offset_field_in(registerread_offset_field),           // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
    .immediate_field_in(registerread_immediate_field),     // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
    .scale_factor_in(registerread_scale_factor),           // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
    .index_limit_in(registerread_index_limit),             // The field indicated by offset_field contains a limit to the index    
    .rd_val_in(registerread_rd_val),                       // value of register operand RD, bit `RB indicates missing 
    .rs_val_in(registerread_rs_val),                       // value of register operand RS, bit `RB indicates missing 
    .rt_val_in(registerread_rt_val),                       // value of register operand RT, bit `RB indicates missing 
    .ru_val_in(registerread_ru_val),                       // value of register operand RU, bit `RB indicates missing 
    .regmask_val_in(registerread_regmask_val),             // mask register
    .write_en1(bus1_write_en),                             // a result is written to bus 1
    .write_tag1_in(bus1_tag),                              // tag of result in bus 1
    .writeport1_in(bus1_value),                            // result bus 1
    .write_en2(bus2_write_en),                             // a result is written to bus 2
    .write_tag2_in(bus2_tag),                              // tag of result in bus 2
    .writeport2_in(bus2_value),                            // result bus 2
    .predict_tag1_in(predict_tag1),                        // tag on result bus 1 in next clock cycle
    .predict_tag2_in(predict_tag2),                        // tag on result bus 2 in next clock cycle
    .read_write_address_out(addrgen_read_write_address),   // address of read memory operand
    .read_enable_out(addrgen_read_enable),                 // enable read from data memory
    .read_data_size_out(addrgen_read_data_size),           // data size for memory read       
    .write_enable_out(addrgen_write_enable),               // write enable for each byte separately 
    .write_data_out(addrgen_write_data),                   // data to write        
    .valid_out(addrgen_valid),                             // An instruction is ready for output to next stage
    .instruction_pointer_out(addrgen_instruction_pointer), // address of current instruction
    .instruction_out(addrgen_instruction),                 // first word of instruction    
    .stall_predict_out(addrgen_stall_next),                // will be waiting for an operand        
    .tag_val_out(addrgen_tag_val),                         // instruction tag value    
    .operand1_out(addrgen_operand1),                       // value of first operand, bit `RB indicates invalid 
    .operand2_out(addrgen_operand2),                       // value of second operand, bit `RB indicates invalid 
    .operand3_out(addrgen_operand3),                       // value of last, bit `RB indicates valid 
    .regmask_val_out(addrgen_regmask_val),                 // value of mask register, bit 32 indicates valid    
    .vector_out(addrgen_vector),                           // this is a vector instruction
    .category_out(addrgen_category),                       // 00: multiformat, 01: single format, 10: jump
    .format_out(addrgen_format),                           // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)    
    .mask_status_out(addrgen_mask_status),                 // 1: mask register used
    .mask_alternative_out(addrgen_mask_alternative),       // mask register and fallback register used for alternative purposes
    .fallback_use_out(addrgen_fallback_use),               // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
    .num_operands_out(addrgen_num_operands),               // number of source operands    
    .result_type_out(addrgen_result_type),                 // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .offset_field_out(addrgen_offset_field),               // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
    .immediate_field_out(addrgen_immediate_field),         // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit    
    .scale_factor_out(addrgen_scale_factor),               // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
    .memory_operand_out(addrgen_memory_operand),           // The instruction has a memory operand
    .array_error_out(addrgen_array_error),                 // Array index exceeds limit
    .options3_out(addrgen_options3),                       // IM3 containts option bits
    .debug1_out(addrgen_debug1),                           // Temporary output for debugging purpose
    .debug2_out(addrgen_debug2),                           // Temporary output for debugging purpose                
    .debug3_out(addrgen_debug3)                            // Temporary output for debugging purpose                
);

dataread dataread_inst (
    .clock(clock),                                         // system clock
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset. 
    .valid_in(addrgen_valid),                              // data from fetch module ready
    .stall_in(dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next),   // pipeline is stalled 
    .instruction_pointer_in(addrgen_instruction_pointer),  // address of current instruction
    .instruction_in(addrgen_instruction),                  // current instruction, up to 3 words long
    .tag_val_in(addrgen_tag_val),                          // instruction tag value    
    .vector_in(addrgen_vector),                            // this is a vector instruction
    .category_in(addrgen_category),                        // 00: multiformat, 01: single format, 10: jump
    .format_in(addrgen_format),                            // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
    .mask_status_in(addrgen_mask_status),                  // 1: mask register used
    .mask_alternative_in(addrgen_mask_alternative),        // mask register and fallback register used for alternative purposes
    .num_operands_in(addrgen_num_operands),                // number of source operands
    .result_type_in(addrgen_result_type),                  // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .immediate_field_in(addrgen_immediate_field),          // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
    .memory_operand_in(addrgen_memory_operand),            // the instruction has a memory operand
    .array_error_in(addrgen_array_error),                  // Array index exceeds limit
    .options3_in(addrgen_options3),                        // IM3 containts option bits
    .write_en1(bus1_write_en),                             // a result is written to bus 1
    .write_tag1_in(bus1_tag),                              // tag of result in bus 1
    .writeport1_in(bus1_value),                            // result bus 1
    .write_en2(bus2_write_en),                             // a result is written to bus 2
    .write_tag2_in(bus2_tag),                              // tag of result in bus 2
    .writeport2_in(bus2_value),                            // result bus 2
    .predict_tag1_in(predict_tag1),                        // result tag value on bus 1 in next clock cycle
    .predict_tag2_in(predict_tag2),                        // result tag value on bus 2 in next clock cycle
    .operand1_in(addrgen_operand1),                        // value of first operand
    .operand2_in(addrgen_operand2),                        // value of second operand
    .operand3_in(addrgen_operand3),                        // value of last operand
    .regmask_val_in(addrgen_regmask_val),                  // mask register
    .address_in(addrgen_read_write_address),               // address of memory operand
    .ram_data_in(data_memory_data),                        // memory operand from data memory
    .valid_out(dataread_valid),                            // An instruction is ready for output to next stage
    .instruction_pointer_out(dataread_instruction_pointer),// address of current instruction
    .instruction_out(dataread_instruction),                // first word of instruction    
    .stall_predict_out(dataread_stall_predict),            // predict next stage will stall
    .tag_val_out(dataread_tag_val),                        // instruction tag value
    .operand1_out(dataread_operand1),                      // value of first operand for 3-op instructions, bit `RB is 0 if valid 
    .operand2_out(dataread_operand2),                      // value of second operand, bit `RB is 0 if valid 
    .operand3_out(dataread_operand3),                      // value of last operand, bit `RB is 0 if valid
    .mask_val_out(dataread_mask_val),                      // value of mask, bit 32 is 0 if valid
    .opr2_from_ram_out(dataread_opr2_from_ram),            // value of operand 2 comes from data memory
    .opr3_from_ram_out(dataread_opr3_from_ram),            // value of last operand comes from data memory
    .vector_out(dataread_vector),                          // this is a vector instruction
    .category_out(dataread_category),                      // 00: multiformat, 01: single format, 10: jump
    .format_out(dataread_format),                          // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
    .num_operands_out(dataread_num_operands),              // number of source operands
    .result_type_out(dataread_result_type),                // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .opr1_used_out(dataread_opr1_used),                    // operand1 is needed
    .opr2_used_out(dataread_opr2_used),                    // operand2 is needed
    .opr3_used_out(dataread_opr3_used),                    // operand3 is needed
    .regmask_used_out(dataread_regmask_used),              // regmask_val_out is needed
    .mask_alternative_out(dataread_mask_alternative),      // mask register and fallback register used for alternative purposes
    .exe_unit_out(dataread_exe_unit),                      // each bit enables a particular execution unit
    .opx_out(dataread_opx),                                // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
    .opj_out(dataread_opj),                                // operation ID for conditional jump instructions
    .ot_out(dataread_ot),                                  // operand type
    .option_bits_out(dataread_option_bits),                // instruction option bits
    .im2_bits_out(dataread_im2_bits),                      // constant bits from IM2 as extra operand        
    .trap_out(dataread_trap),                              // trap instruction detected
    .array_error_out(dataread_array_error),                // array index out of bounds
    .read_address_error_out(dataread_read_address_error),  // invalid read memory address
    .write_address_error_out(dataread_write_address_error),// invalid write memory address
    .misaligned_address_error_out(dataread_misaligned_address_error), // misaligned read/write memory address
    .debug_out(dataread_debug)                             // output for debugging 
);

alu alu_inst (
    .clock(clock),                                         // system clock
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset. 
    .valid_in(dataread_valid & dataread_exe_unit[0]),      // data from previous stage ready
    .stall_in(alu_stall_next | muldiv_stall_next | inout_stall_next),// pipeline is stalled
    .instruction_pointer_in(dataread_instruction_pointer), // address of current instruction
    .instruction_in(dataread_instruction),                 // current instruction, first word only
    .tag_val_in(dataread_tag_val),                         // instruction tag value    
    .category_in(dataread_category),                       // 00: multiformat, 01: single format, 10: jump
    .mask_alternative_in(dataread_mask_alternative),       // mask register and fallback register used for alternative purposes
    .result_type_in(dataread_result_type),                 // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .vector_in(dataread_vector),                           // vector instruction
    .opx_in(dataread_opx),                                 // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
    .opj_in(dataread_opj),                                 // operation ID for conditional jump instructions
    .ot_in(dataread_ot),                                   // operand type    
    .option_bits_in(dataread_option_bits),                 // option bits from IM3 or mask
    .im2_bits_in(dataread_im2_bits),                       // constant bits from IM2 as extra operand    
    
    // monitor result buses:
    .write_en1(bus1_write_en),                             // a result is written to bus 1
    .write_tag1_in(bus1_tag),                              // tag of result in bus 1
    .writeport1_in(bus1_value),                            // result bus 1
    .write_en2(bus2_write_en),                             // a result is written to bus 2
    .write_tag2_in(bus2_tag),                              // tag of result in bus 2
    .writeport2_in(bus2_value),                            // result bus 2
    .predict_tag1_in(predict_tag1),                        // result tag value on bus 1 in next clock cycle
    .predict_tag2_in(predict_tag2),                        // result tag value on bus 2 in next clock cycle    
    // Register values sampled from result bus in previous stages
    .operand1_in(dataread_operand1),                       // first operand or fallback value
    .operand2_in(dataread_operand2),                       // second operand value
    .operand3_in(dataread_operand3),                       // last operand value
    .regmask_val_in(dataread_mask_val),                    // mask register
    .ram_data_in(data_memory_data),                        // memory operand from data memory
    .opr2_from_ram_in(dataread_opr2_from_ram),             // value of operand 2 comes from data memory
    .opr3_from_ram_in(dataread_opr3_from_ram),             // value of last operand comes from data memory
    .opr1_used_in(dataread_opr1_used),                     // opr1_val_in is needed
    .opr2_used_in(dataread_opr2_used),                     // opr2_val_in is needed
    .opr3_used_in(dataread_opr3_used),                     // opr3_val_in is needed    
    .regmask_used_in(dataread_regmask_used),               // regmask_val_in is needed
    .valid_out(alu_valid),                                 // alu is active
    .register_write_out(alu_write_en),                     // write enable for bus 1 
    .register_a_out(alu_register_a),                       // register to write
    .result_out(alu_result),                               // 
    .tag_val_out(alu_tag),                                 // instruction tag value
    .jump_out(alu_jump),                                   //  jump instruction: jump taken
    .nojump_out(alu_nojump),                               // jump instruction: jump not taken
    .jump_pointer_out(alu_jump_pointer),                   // jump target to fetch unit
    .stall_out(alu_stall),                                 // alu is waiting for an operand or not ready to receive a new instruction 
    .stall_next_out(alu_stall_next),                       // alu will be waiting in next clock cycle 
    .error_out(alu_error),                                 // unknown instruction
    .error_parm_out(alu_error_parm),                       // wrong parameter for instruction
    .debug1_out(alu_debug1),                               // debug information
    .debug2_out(alu_debug2)                                // debug information
);

mul_div muldiv_inst (
    .clock(clock),                                         // system clock
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset. 
    .valid_in(dataread_valid & (dataread_exe_unit[1] | dataread_exe_unit[2])), // data from previous stage ready
    .stall_in(alu_stall_next | muldiv_stall_next | inout_stall_next),// pipeline is stalled
    .instruction_in(dataread_instruction[31:0]),           // current instruction, up to 3 words long
    .tag_val_in(dataread_tag_val),                         // instruction tag value    
    .category_in(dataread_category),                       // 00: multiformat, 01: single format, 10: jump
    .mask_alternative_in(dataread_mask_alternative),       // mask register and fallback register used for alternative purposes
    .result_type_in(dataread_result_type),                 // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .vector_in(dataread_vector),                           // vector instruction
    .opx_in(dataread_opx),                                 // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
    .ot_in(dataread_ot),                                   // operand type    
    .option_bits_in(dataread_option_bits),                 // option bits from IM3 or mask
    
    // monitor result buses:
    .write_en1(bus1_write_en),                             // a result is written to bus 1
    .write_tag1_in(bus1_tag),                              // tag of result in bus 1
    .writeport1_in(bus1_value),                            // result bus 1
    .write_en2(bus2_write_en),                             // a result is written to bus 2
    .write_tag2_in(bus2_tag),                              // tag of result in bus 2
    .writeport2_in(bus2_value),                            // result bus 2
    .predict_tag1_in(predict_tag1),                        // result tag value on bus 1 in next clock cycle
    .predict_tag2_in(predict_tag2),                        // result tag value on bus 2 in next clock cycle    
    // Register values sampled from result bus in previous stages
    .operand1_in(dataread_operand1),                       // first operand or fallback value
    .operand2_in(dataread_operand2),                       // second operand value
    .operand3_in(dataread_operand3),                       // last operand value
    .regmask_val_in(dataread_mask_val),                    // mask register
    .ram_data_in(data_memory_data),                        // memory operand from data memory
    .opr2_from_ram_in(dataread_opr2_from_ram),             // value of operand 2 comes from data memory
    .opr3_from_ram_in(dataread_opr3_from_ram),             // value of last operand comes from data memory
    .opr1_used_in(dataread_opr1_used),                     // opr1_val_in is needed
    .opr2_used_in(dataread_opr2_used),                     // opr2_val_in is needed
    .opr3_used_in(dataread_opr3_used),                     // opr3_val_in is needed    
    .regmask_used_in(dataread_regmask_used),               // regmask_val_in is needed
    
    .valid_out(muldiv_valid),                              // alu is active
    .register_write_out(muldiv_write_en),                  // write enable for bus 1 
    .register_a_out(muldiv_register_a),                    // register to write
    .result_out(muldiv_result),                            // 
    .tag_val_out(muldiv_tag),                              // instruction tag value
    .stall_out(muldiv_stall),                              // alu is waiting for an operand or not ready to receive a new instruction 
    .stall_next_out(muldiv_stall_next),                    // alu will be waiting in next clock cycle 
    .error_out(muldiv_error),                              // unknown instruction
    .error_parm_out(muldiv_error_parm),                    // wrong parameter for instruction
    .debug1_out(muldiv_debug1),                            // debug information
    .debug2_out(muldiv_debug2)                             // debug information
);

/***************************************************
       Input and output ports
***************************************************/

in_out_ports in_out_ports_inst (
    .clock(clock),                                         // system clock
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset(system_reset),                                  // system reset
    .valid_in(dataread_valid & dataread_exe_unit[3]),      // data from previous stage ready
    .stall_in(alu_stall_next | muldiv_stall_next | inout_stall_next),// pipeline is stalled
    .instruction_in(dataread_instruction[31:0]),           // current instruction, up to 3 words long
    .tag_val_in(dataread_tag_val),                         // instruction tag value    
    .category_in(dataread_category),                       // 00: multiformat, 01: single format, 10: jump
    .result_type_in(dataread_result_type),                 // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
    .mask_alternative_in(dataread_mask_alternative),       // mask register and fallback register used for alternative purposes
    .vector_in(dataread_vector),                           // vector instruction
    .opx_in(dataread_opx),                                 // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
    .opj_in(dataread_opj),                                 // operation ID for conditional jump instructions
    .ot_in(dataread_ot),                                   // operand type
    .regmask_used_in(dataread_regmask_used),               // regmask_val_in is needed
    
    // connections to UART
    .uart_bit_in(uart_txd_in),                             // serial input
    .uart_rts_in(uart_rts_in),                             // ready to send input
    
    // monitor result buses:
    .write_en1(bus1_write_en),                             // a result is written to bus 1
    .write_tag1_in(bus1_tag),                              // tag of result in bus 1
    .writeport1_in(bus1_value),                            // result bus 1
    .write_en2(bus2_write_en),                             // a result is written to bus 2
    .write_tag2_in(bus2_tag),                              // tag of result in bus 2
    .writeport2_in(bus2_value),                            // result bus 2
    .predict_tag1_in(predict_tag1),                        // result tag value on bus 1 in next clock cycle
    .predict_tag2_in(predict_tag2),                        // result tag value on bus 2 in next clock cycle    
    
    // Register values sampled from result bus in previous stages
    .operand1_in(dataread_operand1),                       // first operand or fallback value
    .operand2_in(dataread_operand2),                       // second operand
    .operand3_in(dataread_operand3),                       // last operand
    .regmask_val_in(dataread_mask_val),                    // mask register
    .opr1_used_in(dataread_opr1_used),                     // opr1_val_in is needed
    
    // signals used for performance monitoring
    .instruction_valid_in(dataread_valid),                 // instruction is valid but possibly going to a different exe unit
    .fast_jump_in(fetch_jump),                             // a jump is bypassing the pipeline
    .errors_detect_in(errors_detect),                      // one bit for each type of error detected
    .fetch_instruction_pointer(fetch_instruction_pointer),
    .dataread_instruction_pointer(dataread_instruction_pointer),
    .dataread_valid(dataread_valid),                       // used when reconstructing alu_instruction_pointer
    .call_stack_overflow(call_stack_overflow),             // used for differentiating errors_detect_in[1]
    .clear_error_in(clear_error),                          // debug clear error    
    
    // outputs
    .valid_out(inout_valid),                               // in_out is active
    .register_write_out(inout_write_en), 
    .register_a_out(inout_register_a),                     // register to write
    .result_out(inout_result),                
    .tag_val_out(inout_tag),                               // instruction tag value   
    .nojump_out(inout_nojump),                             // serializing instruction finished
    .stall_out(inout_stal),                                // alu is waiting for an operand or not ready to receive a new instruction 
    .stall_next_out(inout_stall_next),                     // alu will be waiting in next clock cycle 
    .error_out(inout_error),                               // unknown instruction
    .error_parm_out(inout_error_parm),                     // wrong parameter for instruction
    .uart_bit_out(uart_rxd_out),                           // serial output
    .uart_cts_out(uart_cts_out),                           // clear to send output
    .capab_disable_errors(inout_capab_disable_errors),     // capab2 register: disable errors
    .first_error(inout_first_error),                       // error type for first error
    .first_error_address(inout_first_error_address),       // code address of first error
    .debug_out(inout_debug)                                // debug information
);

/***************************************************
       Debugging signals
***************************************************/

// debug display
debug_display debug_display_inst (
    .clock(clock),                                         // system clock (50 - 100 MHz)
    .clock_enable(clock_enable),                           // clock enable. Used when single-stepping
    .reset_button_debounced(reset_button_debounced),       // reset button      
    
    // from fetch stage
    .fetch_instruction(fetch_instruction[63:0]),           // first words of instruction
    .fetch_instruction_pointer(fetch_instruction_pointer), // point to current instruction
    .fetch_valid(fetch_valid),                             // output from fetch is ready
    .fetch_jump(fetch_jump),                               // jump instruction bypassing pipeline
    .fetch_call_e(fetch_call_e),                           // executing call instruction
    .fetch_return_e(fetch_return_e),                       // executing return instruction
    .registerread_stall_predict(registerread_stall_predict),// address generation stalled next
    .addrgen_stall_next(addrgen_stall_next),
    .dataread_stall_predict(dataread_stall_predict),       // alu stalled next
    .alu_stall_next(alu_stall_next),                       // alu stalled next
    .muldiv_stall_next(muldiv_stall_next),                 // muldiv stalled next
    .inout_stall_next(inout_stall_next),                   // in_out_ports stalled next
    // from decoder
    .decoder_instruction(decoder_instruction[63:0]),       // first words of instruction    
    .decoder_instruction_pointer(decoder_instruction_pointer), // address of current instruction
    .decoder_valid(decoder_valid),                         // output from decoder is ready
    // from register_read
    .registerread_instruction(registerread_instruction[63:0]), // first words of instruction    
    .registerread_instruction_pointer(registerread_instruction_pointer), // address of current instruction
    .registerread_valid(registerread_valid),               // output from decode_wait is ready
    // from address generator
    .addrgen_instruction(addrgen_instruction[63:0]),       // first words of instruction    
    .addrgen_instruction_pointer(addrgen_instruction_pointer), // address of current instruction
    .addrgen_valid(addrgen_valid),                         // output from addrgen is ready
    // from address_wait
    .dataread_instruction(dataread_instruction),           // first words of instruction    
    .dataread_instruction_pointer(dataread_instruction_pointer), // address of current instruction
    .dataread_opx(dataread_opx),                           // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
    .dataread_valid(dataread_valid),                       // output from addrwait is ready
    .dataread_operand1(dataread_operand1),                 // first register operand RD or RU
    .dataread_operand2(dataread_operand2),                 // second register operand RS
    .dataread_operand3(dataread_operand3),                 // last register operand RT
    .dataread_mask_val(dataread_mask_val),                 // mask register value
    .ram_data_in(data_memory_data[15:0]),                  // memory operand from data memory
    .dataread_opr2_from_ram(dataread_opr2_from_ram),       // value of operand 2 comes from data ram
    .dataread_opr3_from_ram(dataread_opr3_from_ram),       // value of last operand comes from data ram 

    // from ALU    
    //.writea1(bus1_register_a),                           // register to write
    .alu_result(bus1_value[31:0]),                         // 
    .write_tag1(bus1_tag),    
    .alu_valid(alu_valid | muldiv_valid | inout_valid),    // alu or in_out is ready
    .alu_jump(alu_jump),                                   // jump instruction: jump taken
    //.alu_nojump(alu_nojump),                             // jump instruction: jump not taken
    .alu_jump_pointer(alu_jump_pointer),
    
    // from result buses
    .writeport2(bus2_value[31:0]),
    .write_en2(bus2_write_en),
    .write_tag2(bus2_tag),    
    
    // output to display
    .lcd_rs(lcd_rs),                                       // LCD RS pin
    .lcd_e(lcd_e),                                         // enable pins for two LCD displays
    .lcd_data(lcd_data)                                    // LCD data, 4 bit bus    
);
    

`include "debugger.vh"

assign led0 = load_button_debounced;
assign led1 = reset_button_debounced; 
assign led2 = run_button_debounced; 
assign led3 = step_button_debounced; 

assign led4 = fetch_call_e;                                // vacant. connected to something just to avoid warning
assign led5 = fetch_return_e;
assign led6 = fetch_valid;
assign led7 = system_reset;

/*
assign led12 = registerread_stall_predict;
assign led13 = addrgen_stall_next;
assign led14 = dataread_stall_predict;
assign led15 = alu_stall_next;
*/
// temporary led assignments
assign led12 = call_stack_overflow;
assign led13 = alu_error_parm | muldiv_error_parm;
assign led14 = inout_error_parm;
assign led15 = show_error;

// RGB led
assign led16R = color_led16[0];
assign led16G = color_led16[1];
assign led16B = color_led16[2];

endmodule

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

powered by: WebSVN 2.1.0

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