📄 nios_0.v
字号:
4'b1010: skip_condition = status [2]; //V
4'b1011: skip_condition = ~status [2]; //~V
4'b1100: skip_condition = status [0] | status [1]; //C or Z
4'b1101: skip_condition = ~(status [0] | status [1]); //~ (C or Z)
default: skip_condition = 1'bx;
endcase
end
// Mealy-type FSM - combinational part
// The following signals are controlled directly by an FSM:
// d_read - d_read signal that is fed to the Avalon bus
// d_write - d_write signal that is fed to the Avalon bus
// decrement_cwp - signals that CWP should be decremented because of SAVE or TRAP
// disable_interrupts - sinnals that interrupts should be disabled because an interrupt
// is just being accepted
// flush_fifo - signals that the prefetch FIFO buffer should be flushed
// because of a control-flow instruction
// force_interrupt - signals that a TRAP instruction with number d_irqnumber
// should be pushed inte the pipeline
// force_trap_1 - signals that TRAP 1 should be pushed into pipeline
// force_trap_2 - signals that TRAP 2 should be pushed into pipeline
// increment_cwp - signals that CWP should be incremented because of RESTORE
// read_next - signals that the instruction currently in the execute stage
// has finished execution, and the next instruction can be read
// reg_write - write-enable signal for the register file
// skip - signals that the instruction currently in the execute stage
// is being skipped
always @ (*)
begin
case (state)
// State READ_AND_EXECUTE is a central state where most of the instructions are handled
READ_AND_EXECUTE:
begin
// If there is an interrupt request, handle it
// Notice that interrupts are only handled in READ_AND_EXECUTE stage
if (interrupt_reg == 1)
begin
d_read = 0;
d_write = 0;
decrement_cwp = 0; // It will be done when TRAP gets into the pipeline
disable_interrupts = 1;
flush_fifo = 0;
force_interrupt = 1;
force_trap_1 = 0;
force_trap_2 = 0;
increment_cwp = 0;
read_next = 1;
reg_write = 0;
skip = 0;
next_state = READ_AND_EXECUTE;
end
// If the instruction is not available, wait for it
else if (ctrl_en == 0)
begin
d_read = 0;
d_write = 0;
decrement_cwp = 0;
disable_interrupts = 0;
flush_fifo = 0;
force_interrupt = 0;
force_trap_1 = 0;
force_trap_2 = 0;
increment_cwp = 0;
read_next = 1;
reg_write = 0;
skip = 0;
next_state = READ_AND_EXECUTE;
end
else
begin
// Perform the operations appropriate for a given instruction type
// Many signals are set to 0 here, but are overridden later in the code
// (by Verilog semantics, only the last assignment is valid)
d_read = 0;
d_write = 0;
decrement_cwp = 0;
disable_interrupts = 0;
flush_fifo = 0;
force_interrupt = 0;
force_trap_1 = 0;
force_trap_2 = 0;
increment_cwp = 0;
// Register write needs to be enabled only for instructions that write the value
// to the register (this information is encoded in the two lowest bits of the
// decoded instruction (see instruction decoder signals for further explanation)
reg_write = (decoded_instr[1] | decoded_instr[0]);
// If the instruction is a skip check the condition
if (skprnz) // SKPRNZ
begin
read_next = 1;
if (RA != 32'b0)
begin
flush_fifo = 0;
skip = 1;
next_state = CHECK_PFX;
end
else // If the skip condition is not satisfied, continue with execution
begin
// FIFO has to be flushed if the instruction in the operand stage is
// a control-flow instruction
flush_fifo = next_is_ctrl_flow_instr;
skip = 0;
next_state = READ_AND_EXECUTE;
end
end
else if (skprz) // SKPRZ
begin
read_next = 1;
if (RA == 32'b0)
begin
flush_fifo = 0;
skip = 1;
next_state = CHECK_PFX;
end
else // If the skip condition is not satisfied, continue with execution
begin
flush_fifo = next_is_ctrl_flow_instr;
skip = 0;
next_state = READ_AND_EXECUTE;
end
end
else if (skp1) // SKP1
begin
read_next = 1;
// Condition for SKP1 is RA[imm5]==1
if (RA[ir[9:5]] == 1)
begin
flush_fifo = 0;
skip = 1;
next_state = CHECK_PFX;
end
else // If the skip condition is not satisfied, continue with execution
begin
flush_fifo = next_is_ctrl_flow_instr;
skip = 0;
next_state = READ_AND_EXECUTE;
end
end
else if (skp0) // SKP0
begin
read_next = 1;
// Condition for SKP0 is RA[imm5]==0
if (RA[ir[9:5]] == 0)
begin
flush_fifo = 0;
skip = 1;
next_state = CHECK_PFX;
end
else // If the skip condition is not satisfied, continue with execution
begin
flush_fifo = next_is_ctrl_flow_instr;
skip = 0;
next_state = READ_AND_EXECUTE;
end
end
else if (skps) // SKPS
begin
read_next = 1;
// Skip is performed or not, based on the encoded condition
// If the skip condition is satisfied, the next instruction is skipped
if (skip_condition == 1)
begin
flush_fifo = 0;
skip = 1;
next_state = CHECK_PFX;
end
else // If the skip condition is not satisfied, continue with execution
begin
flush_fifo = next_is_ctrl_flow_instr;
skip = 0;
next_state = READ_AND_EXECUTE;
end
end
else if (save)
begin
// SAVE instruction
d_read = 0;
d_write = 0;
increment_cwp = 0;
read_next = 1;
skip = 0;
// If cwp == lo_limit, we need to call TRAP #1
if (cwp_is_lo_limit)
begin
// But only if the underflow should be handled (interrupts are enabled, and
// IPRI is greater than 1)
if (handle_underflow)
begin
decrement_cwp = 0; // It will be done when TRAP gets to pipeline
disable_interrupts = 1;
flush_fifo = 0; // If SAVE causes trap, possible branch after it shouldn't be executed
force_trap_1 = 1;
read_next = 1; // We read the instruction being pushed into the pipeline
next_state = READ_AND_EXECUTE;
end
else // Otherwise the underflow is not handled, and the execution resumes normally
begin
decrement_cwp = 1;
disable_interrupts = 0;
flush_fifo = next_is_ctrl_flow_instr;
force_trap_1 = 0;
read_next = 1;
next_state = READ_AND_EXECUTE;
end
end
else // Otherwise there is no underflow to handle, and the execution resumes normally
begin
decrement_cwp = 1;
disable_interrupts = 0;
flush_fifo = next_is_ctrl_flow_instr;
force_trap_1 = 0;
read_next = 1;
next_state = READ_AND_EXECUTE;
end
end
else if (restore)
begin
// RESTORE instruction
d_read = 0;
d_write = 0;
decrement_cwp = 0;
skip = 0;
// If cwp == hi_limit, we need to call TRAP #2
if (cwp_is_hi_limit)
begin
// But only if overflows should be handled (interrupts are enabled, and
// IPRI is greater than 2)
if (handle_overflow)
begin
disable_interrupts = 1;
flush_fifo = 0; // If RESTORE causes trap, possible branch after it shouldn't be executed
force_trap_2 = 1;
increment_cwp = 1; // It will be decreased when TRAP gets to pipeline
read_next = 1; // So we read the instruction being pushed into pipeline
next_state = READ_AND_EXECUTE;
end
else // Otherwise the overflow is not handled, and the execution resumes normally
begin
disable_interrupts = 0;
flush_fifo = next_is_ctrl_flow_instr;
force_trap_2 = 0;
increment_cwp = 1;
read_next = 1;
next_state = READ_AND_EXECUTE;
end
end
else // Otherwise there is no overflow to handle, and the execution resumes normally
begin
disable_interrupts = 0;
flush_fifo = next_is_ctrl_flow_instr;
force_trap_2 = 0;
increment_cwp = 1;
read_next = 1;
next_state = READ_AND_EXECUTE;
end
end
else if (trap)
begin
//TRAP instruction
d_read = 1;
d_write = 0;
decrement_cwp = 1;
disable_interrupts = 1;
flush_fifo = 0;
increment_cwp = 0;
read_next = 0;
skip = 0;
next_state = TRAP;
end
else if (tret)
begin
//TRET instruction
d_read = 0;
d_write = 0;
decrement_cwp = 0;
flush_fifo = 0;
increment_cwp = 0;
read_next = 1;
skip = 0;
next_state = READ_AND_EXECUTE;
end
else if (ld)
begin
//One of the LD instructions
`ifdef ZERO_LATENCY
d_read = 0;
flush_fifo = 0;
skip = 0;
if (d_wait == 1)
begin
read_next = 0;
reg_write = 0;
next_state = LOAD;
end
else
begin
if (next_is_ctrl_flow_instr) flush_fifo = 1;
read_next = 1;
// Write the value from memory into the register file
reg_write = 1;
next_state = READ_AND_EXECUTE;
end
`else
d_read = 1;
flush_fifo = 0;
read_next = 0;
skip = 0;
next_state = LOAD;
`endif
end
else if (st)
begin
//One of the ST instructions
`ifdef ZERO_LATENCY
d_write = 1;
flush_fifo = next_is_ctrl_flow_instr;
skip = 0;
if (d_wait == 1)
begin
read_next = 0;
next_state = STORE;
end
else
begin
read_next = 1;
next_state = READ_AND_EXECUTE;
end
`else
d_write = 1;
flush_fifo = next_is_ctrl_flow_instr;
read_next = 0;
skip = 0;
next_state = STORE;
`endif
end
else
begin
// All other instructions are handled with the same signal values
d_read = 0;
d_write = 0;
decrement_cwp = 0;
flush_fifo = next_is_ctrl_flow_instr;
increment_cwp = 0;
read_next = 1;
skip = 0;
next_state = READ_AND_EXECUTE;
end
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -