diff --git a/system/processor.v b/system/processor.v index 39953c2..f62b6e4 100644 --- a/system/processor.v +++ b/system/processor.v @@ -198,7 +198,10 @@ always @(negedge reset) begin end always @(posedge reset) begin proc_state <= `PROC_RESET; - valid_instruction_ack <= 0; // needs early init + /* need early init */ + valid_instruction_ack <= 0; + instant_response <= 0; + stalled_response <= 0; end /*** Processor stages ***/ @@ -216,29 +219,55 @@ reg owe_set_init; reg VALID_INSTRUCTION_lc; always @(VALID_INSTRUCTION)begin VALID_INSTRUCTION_lc<=VALID_INSTRUCTION; end +reg instant_response, stalled_response; +reg wait_exec; + always @(next_exec) begin proc_state<=`PROC_DE_STATE_ENTRY; - if ( VALID_INSTRUCTION_lc == 1 && SIMPLE_MICRO == 0 && DE_DEPENDS_ON_PREVIOUS == 0 && ucode_seq_addr_entry==`UCODE_NO_INSTRUCTION) begin + if ( VALID_INSTRUCTION_lc == 1 && DE_DEPENDS_ON_PREVIOUS == 0 && ucode_seq_addr_entry==`UCODE_NO_INSTRUCTION) begin + instant_response <= !instant_response; + end else begin + wait_exec<=0; + end +end + +always @(instant_response or stalled_response) begin + DE_OUTPUT_sampled <= DE_OUTPUT; + + if(SIMPLE_MICRO==0||owe_set_init==1)begin + /* This runs at the start of the execution of an 8086 instruction */ `ifdef DEBUG_PC_ADDRESS $display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,INSTRUCTION); `endif `ifdef CALCULATE_IPC new_instruction <= !new_instruction; `endif - DE_OUTPUT_sampled <= DE_OUTPUT; - set_initial_values<= !set_initial_values; valid_instruction_ack <= !valid_instruction_ack; + owe_set_init<=0; + set_initial_values<= !set_initial_values; ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end}; INSTRUCTION_BUFFER<=INSTRUCTION[23:0]; - wait_exec<=1; - valid_exec_data<=!valid_exec_data; + end + + if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin + /* switch to microcode decoding */ + ucode_seq_addr <= ucode_seq_addr_entry; + SIMPLE_MICRO <= 1; + /*keep proc_state the same and rerun decode this time with all the data from the microcode rom*/ end else begin - wait_exec<=0; + /* This runs at the start of each execution cycle, with microcode this is more than once per 8086 instruction */ + valid_exec_data<=!valid_exec_data; + if( SIMPLE_MICRO == 1 ) begin + ucode_seq_addr <= ucode_seq_addr_entry; /*Reused for next address*/ + if( ucode_seq_addr_entry == `UCODE_NO_INSTRUCTION )begin + /*Finished microcode*/ + SIMPLE_MICRO <= 0; + end + end + wait_exec<=1; end end -reg wait_exec; - always @(posedge clock) begin case(proc_state) `PROC_RESET:begin @@ -252,43 +281,8 @@ always @(posedge clock) begin valid_exec_data<=0; end `PROC_DE_STATE_ENTRY:begin - if( VALID_INSTRUCTION==1 || SIMPLE_MICRO == 1 ) begin - if(wait_exec==0) begin - DE_OUTPUT_sampled <= DE_OUTPUT; - - if(SIMPLE_MICRO==0||owe_set_init==1)begin - /* This runs at the start of the execution of an 8086 instruction */ - `ifdef DEBUG_PC_ADDRESS - $display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,INSTRUCTION); - `endif - `ifdef CALCULATE_IPC - new_instruction <= !new_instruction; - `endif - valid_instruction_ack <= !valid_instruction_ack; - owe_set_init<=0; - set_initial_values<= !set_initial_values; - ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end}; - INSTRUCTION_BUFFER<=INSTRUCTION[23:0]; - end - - if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin - /* switch to microcode decoding */ - ucode_seq_addr <= ucode_seq_addr_entry; - SIMPLE_MICRO <= 1; - /*keep proc_state the same and rerun decode this time with all the data from the microcode rom*/ - end else begin - /* This runs at the start of each execution cycle, with microcode this is more than once per 8086 instruction */ - valid_exec_data<=!valid_exec_data; - if( SIMPLE_MICRO == 1 ) begin - ucode_seq_addr <= ucode_seq_addr_entry; /*Reused for next address*/ - if( ucode_seq_addr_entry == `UCODE_NO_INSTRUCTION )begin - /*Finished microcode*/ - SIMPLE_MICRO <= 0; - end - end - wait_exec<=1; - end - end + if ( ( VALID_INSTRUCTION==1 || SIMPLE_MICRO == 1 ) && wait_exec==0) begin + stalled_response <= !stalled_response; end end `PROC_HALT:begin