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

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [debugger.vh] - Rev 36

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

//////////////////////////////////////////////////////////////////////////////////
// Engineer: Agner Fog 
// 
// Create date:   2020-05-25
// Last modified: 2021-08-03
// Module name:   debugger
// Project name:  ForwardCom soft core
// Tool versions: Vivado 2020.1 
// License: CERN-OHL-W
// Description: Debug feature giving access to any signal in the pipeline.
// The signal to show is selected with input switches and shown on 7-segment displays
//////////////////////////////////////////////////////////////////////////////////
 
// debug output on 7-segment display
// switch 8:0: select what to show on display, according to the cases below.
 
logic [8:0] debug_out_select ;       // select what to show on debug display
reg [7:0]   enable_digits;           // enable each digit
reg [31:0]  debugOut;                // output to debug display
reg [26:0]  clock_counter = 0;       // divide clock by 100E6
reg [15:0]  clock_1 = 0;             // second counter for testing clock frequency
 
always_ff @(posedge clock) begin
 
    // divide clock for testing
    if (clock_counter == 100000000) begin
        clock_counter <= 0;
        clock_1 <= clock_1 + 1;
    end else begin
        clock_counter <= clock_counter + 1;
    end
 
    enable_digits <= 8'b11111111;
    color_led16 <= 0;
 
/*  List the signals you want to be available on the display. You may change this list.
    If you want to see local signals within a module, then the best way is as follows:
    Make one or more debug output registers in the module. Local variables that are not 
    register variables are clocked out to the debug output register. Local variables that
    are already registered should be assigned to the debug output rather than be clocked  
    out in order to prevent an extra clock cycle delay. See fetch.sv for an example.
    All debug signals should apply to the same clock cycle in order to prevent confusion.
    You may comment out some signals in order to save resources.
*/      
    debug_out_select <= {switch8,switch7,switch6,switch5,switch4,switch3,switch2,switch1,switch0};
    case (debug_out_select)    
 
        // fetch unit
        8'b00000000: debugOut <= fetch_instruction[31:0];
        8'b00000001: debugOut <= fetch_instruction[63:32];
        8'b00000010: debugOut <= fetch_instruction[95:64];
        8'b00000011: debugOut <= fetch_instruction_pointer;
        8'b00000100: debugOut <= {fetch_read_enable,{(27-`CODE_ADDR_WIDTH){1'b0}},fetch_read_addr,1'b0}; // fetch_read_addr = half value
        8'b00000101: debugOut <= code_memory_data[31:0];
        8'b00000110: debugOut <= code_memory_data[63:32];
        8'b00000111: debugOut <= {fetch_valid,2'b0,fetch_jump};
        //8'b00001111: debugOut <= call_stack_pop_data;
        8'b00001000: debugOut <= fetch_debug1; 
 
        // decoder
        //8'b00010000: debugOut <= decoder_instruction[31:0];
        //8'b00010001: debugOut <= decoder_instruction[63:32];
        8'b00010010: debugOut <= decoder_instruction_pointer;
        8'b00010100: debugOut <= {decoder_num_operands, 3'b0,decoder_mask_options, 2'b0,decoder_rd_status, 2'b0,decoder_ru_status, 1'b0,decoder_rt_status, 1'b0,decoder_rs_status};
        8'b00010101: debugOut <= {decoder_index_limit,  2'b0,decoder_scale_factor,  2'b0,decoder_offset_field,  2'b0,decoder_result_type};
        8'b00010110: debugOut <= {decoder_num_operands,  2'b0,decoder_format,  2'b0,decoder_category};
        8'b00011000: debugOut <= {decoder_read,decoder_tag_write, 3'b0,decoder_tag_val, 2'b0,decoder_tag_a};
        8'b00011110: debugOut <= {  2'b0,decoder_result_type};
        8'b00011111: debugOut <= decoder_debug1;        
 
        // register read stage
        //8'b00100000: debugOut <= registerread_instruction[31:0];
        8'b00100010: debugOut <= registerread_instruction_pointer;
        8'b00100011: debugOut <= {registerread_num_operands, 2'b0,registerread_rd_status, 2'b0,registerread_ru_status, 1'b0,registerread_rt_status, 1'b0,registerread_rs_status};
        8'b00100100: debugOut <= registerread_fallback_use; 
        8'b00100110: debugOut <= {registerread_stall_predict, 3'b0,registerread_valid};
        8'b00101000: debugOut <= {registerread_rd_val[`RB], 3'b0,registerread_rd_val[27:0]};
        8'b00101001: debugOut <= {registerread_rs_val[`RB], 3'b0,registerread_rs_val[27:0]};
        8'b00101010: debugOut <= {registerread_rt_val[`RB], 3'b0,registerread_rt_val[27:0]};
        8'b00101011: debugOut <= {registerread_ru_val[`RB], 3'b0,registerread_ru_val[27:0]};
        8'b00101100: debugOut <= {registerread_regmask_val[`MASKSZ],3'b0,registerread_rd_val[`RB],3'b0,registerread_rs_val[`RB],3'b0,registerread_rt_val[`RB]};
        8'b00101110: debugOut <= registerread_tag_val;
 
        // address generator        
        //8'b00110000: debugOut <= addrgen_instruction[31:0];
        8'b00110001: debugOut <= addrgen_read_write_address;
        8'b00110011: debugOut <= addrgen_instruction_pointer;
        8'b00110100: debugOut <= {addrgen_stall_next, 3'b0,addrgen_valid};
        8'b00110101: debugOut <= addrgen_result_type;        
        8'b00110110: debugOut <= addrgen_write_enable;
        8'b00110111: debugOut <= addrgen_write_data;
        8'b00111000: debugOut <= {addrgen_operand1[`RB], 3'b0,addrgen_operand1[27:0]};
        8'b00111001: debugOut <= {addrgen_operand2[`RB], 3'b0,addrgen_operand2[27:0]};
        8'b00111010: debugOut <= {addrgen_operand3[`RB], 3'b0,addrgen_operand3[27:0]};
        8'b00111011: debugOut <= addrgen_tag_val;
        8'b00111100: debugOut <= {addrgen_regmask_val[`MASKSZ], 12'b0,addrgen_regmask_val[15:0]};
        8'b00111101: debugOut <= addrgen_debug1;
        8'b00111110: debugOut <= addrgen_debug2;
        8'b00111111: debugOut <= addrgen_debug3;
 
        // dataread stage
        //8'b01000000: debugOut <= dataread_instruction[31:0];
        8'b01000010: debugOut <= dataread_instruction_pointer;
        8'b01000011: debugOut <= {dataread_ot,    dataread_exe_unit, 2'b0,dataread_format, 2'b0,dataread_num_operands, dataread_vector,1'b0,dataread_category};
        8'b01000100: debugOut <= {2'b0,dataread_option_bits,    2'b0,dataread_opj, 1'b0,dataread_opx};
        8'b01000101: debugOut <= {dataread_mask_alternative,dataread_regmask_used};
        8'b01000110: debugOut <= {2'b0,dataread_num_operands, 1'b0,dataread_opr3_used,dataread_opr2_used,dataread_opr1_used};
        8'b01000111: debugOut <= {dataread_im2_bits,  10'b0,dataread_option_bits};        
        8'b01001000: debugOut <= {dataread_operand1[`RB], 3'b0,dataread_operand1[27:0]};
        8'b01001001: debugOut <= {dataread_operand2[`RB], 3'b0,dataread_operand2[27:0]};
        8'b01001010: debugOut <= {dataread_operand3[`RB], 3'b0,dataread_operand3[27:0]};
        8'b01001011: debugOut <= {dataread_mask_val[`MASKSZ], 12'b0,dataread_mask_val[15:0]};
        8'b01001100: debugOut <= {2'b0,dataread_opj,  1'b0,dataread_opx,  2'b0,dataread_instruction[`OP1]};                
        8'b01001101: debugOut <= dataread_tag_val;
        8'b01001110: debugOut <= {dataread_opr3_from_ram,dataread_opr2_from_ram, 2'b0,dataread_result_type};
        8'b01001111: debugOut <= dataread_debug;
 
        // alu
        8'b01010000: debugOut <= bus1_value[31:0];
        8'b01010001: debugOut <= bus1_register_a;
        8'b01010010: debugOut <= {dataread_opx,  dataread_exe_unit, 2'b0,inout_write_en,alu_write_en};
        8'b01010011: debugOut <= {bus1_tag, 3'b0,inout_tag, 3'b0,alu_tag};
        8'b01010100: debugOut <= {inout_write_en,alu_write_en, 2'b0, inout_error,alu_error, 2'b0,alu_nojump,alu_jump};
        8'b01010101: debugOut <= alu_jump_pointer;        
        8'b01010110: debugOut <= {inout_stall_next,alu_stall_next,  2'b0,inout_stall,alu_stall,  3'b0,dataread_stall_predict,  3'b0,addrgen_stall_next,  3'b0,registerread_stall_predict};
        8'b01010111: debugOut <= {alu_tag,  2'b0,alu_register_a, 3'b0,alu_write_en};
        8'b01011000: debugOut <= alu_result;
        8'b01011001: debugOut <= alu_debug1;
        8'b01011010: debugOut <= alu_debug2;        
        8'b01011011: debugOut <= muldiv_debug1;
        8'b01011100: debugOut <= muldiv_debug2;        
        8'b01011111: debugOut <= inout_debug;        
 
        // pipeline synchronization
        8'b01110000: debugOut <= {inout_stall_next,inout_stall,alu_stall_next,alu_stall, 3'b0,dataread_stall_predict, 3'b0,addrgen_stall_next, 3'b0,registerread_stall_predict};
        8'b01110001: debugOut <= {1'b0,alu_jump,alu_nojump,bus1_write_en, 3'b0,dataread_valid,   1'b0,addrgen_write_enable,addrgen_read_enable,addrgen_valid, 3'b0,registerread_valid, 3'b0,decoder_valid, 3'b0,fetch_valid};
        8'b01110010: debugOut <= {bus1_tag, 10'b0,bus1_register_a};
        8'b01111000: debugOut <= {inout_first_error_address,  2'b0,inout_capab_disable_errors,  4'b0,inout_first_error};
        8'b01111111: debugOut <= clock_1; // Test clock frequency. This will count at CLOCK_FREQUENCY / 10^8        
 
        // data memory read / write
        8'b10000000: debugOut <= addrgen_read_write_address;
        8'b10000001: debugOut <= {addrgen_read_data_size,3'b0,addrgen_read_enable};
        8'b10000010: debugOut <= data_memory_data;
        8'b10000101: debugOut <= addrgen_write_enable;
        8'b10000110: debugOut <= addrgen_write_data[31:0];
        //8'b10000111: debugOut <= addrgen_write_data[63:32];
        8'b10001000: debugOut <= code_memory_debug;
 
        default: debugOut <= 32'hFFFFFFFF;   
    endcase
 
    color_led16 <= 0;
    if (show_error) begin
        // show error code. this overrides the switch selection
        /* 1: alu_error | muldiv_error | inout_error;                                      // unknown instruction
           2: alu_error_parm | muldiv_error_parm | inout_error_parm | call_stack_overflow; // wrong parameter for instruction
           3: dataread_array_error;                                                        // array index out of bounds
           4: dataread_read_address_error;                                                 // read address violation
           5: dataread_write_address_error;                                                // write address violation
           6: dataread_misaligned_address_error;                                           // misaligned memory address
        */
        debugOut[31:28] <= 4'b1110;  // "E"
        debugOut[27:24] <= inout_first_error;
        debugOut[23:20] <= 0;  
        debugOut[19:0]  <= inout_first_error_address;  
        enable_digits   <= 8'b11011111;
        // blink LED, 25% brightness
        color_led16[0]  <= clock_counter[1:0] == 0 && clock_counter[24]; 
 
    end else if (switch8) begin
        // look into register file
        debug_reada <= debug_out_select[5:0];
        debugOut <= {registerread_debugport[32],3'b0,registerread_debugport[27:0]};        
    end else begin
        debug_reada <= 0;
    end
end
 
seg7 seg7_inst(clock, debugOut, enable_digits, segment7seg, digit7seg);
 

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.