📄 nios_0.v
字号:
// State CHECK_PFX skips (does not commit) any PFX instructions and an instruction
// following the PFX
CHECK_PFX:
begin
// If the instruction is not available wait for it
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 = 1;
next_state = CHECK_PFX;
end
else
begin
d_read = 0;
d_write = 0;
decrement_cwp = 0;
disable_interrupts = 0;
force_interrupt = 0;
force_trap_1 = 0;
force_trap_2 = 0;
increment_cwp = 0;
read_next = 1;
reg_write = 0;
skip = 1;
// If the instruction is PFX, skip one more instruction
if (pfx)
begin
flush_fifo = 0;
next_state = CHECK_PFX;
end
else
begin
// Else do not commit this instruction, and continue execution with the next one
if (next_is_ctrl_flow_instr) flush_fifo = 1;
else flush_fifo = 0;
next_state = READ_AND_EXECUTE;
end
end
end
// LOAD state waits for the data to become available from memory, and sets signal to write
// it to the register file
LOAD:
begin
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;
skip = 0;
d_read = 1;
// If d_wait signal is set, the data is not ready from memory
if (d_wait == 1)
begin
read_next = 0;
reg_write = 0;
next_state = LOAD;
end
else // Otherwise the data is ready, and needs to be captured by the register file
begin
read_next = 1;
reg_write = 1;
next_state = READ_AND_EXECUTE;
if (next_is_ctrl_flow_instr) flush_fifo = 1;
end
end
// STORE state waits for the data to be written to memory
STORE:
begin
d_read = 0;
d_write = 1;
decrement_cwp = 0;
disable_interrupts = 0;
flush_fifo = 0;
force_interrupt = 0;
force_trap_1 = 0;
force_trap_2 = 0;
increment_cwp = 0;
reg_write = 0;
skip = 0;
// If d_wait signal is set, the data has not yet been written to memory
if (d_wait == 1)
begin
read_next = 0;
next_state = STORE;
end
else
begin
read_next = 1;
next_state = READ_AND_EXECUTE;
end
end
// TRAP state waits for the target address to be fetced from the vector table in memory
TRAP:
begin
//Handling the TRAP instruction
d_read = 1;
d_write = 0;
decrement_cwp = 0;
disable_interrupts = 0;
force_interrupt = 0;
force_trap_1 = 0;
force_trap_2 = 0;
increment_cwp = 0;
reg_write = 0;
skip = 0;
// If d_wait signal is set, the data is not ready from memory
if (d_wait == 1)
begin
flush_fifo = 0;
read_next = 0;
next_state = TRAP;
end
// Otherwise, the data is available, and prefetch unit can start fetching from the
// target address
else
begin
flush_fifo = 1;
read_next = 1;
next_state = READ_AND_EXECUTE;
end
end
// Default section prevents the latch to be inferred
default:
begin
d_read = 1'bx;
d_write = 1'bx;
decrement_cwp = 1'bx;
disable_interrupts = 1'bx;
flush_fifo = 1'bx;
force_interrupt = 1'bx;
force_trap_1 = 1'bx;
force_trap_2 = 1'bx;
increment_cwp = 1'bx;
read_next = 1'bx;
reg_write = 1'bx;
skip = 1'bx;
next_state = STATE_X;
end
endcase
end
// Mealy-type FSM - sequential part
always @ (posedge clk or negedge reset_n)
begin
if (reset_n == 0)
begin
state <= READ_AND_EXECUTE;
end
else
begin
state <= next_state;
end
end
endmodule
//control_unit***************************************************************
//***************************************************************************
// datapath
//
// Module datapath instantaites all the modules of the datapath
// (pipeline stages and pipeline registers)
//
module datapath (
// inputs
clk,
current_reg_write_en,
d_irqnumber,
d_readdata,
decrement_cwp,
disable_interrupts,
flush_pipeline,
flush_fifo,
force_interrupt,
force_read,
force_trap_1,
force_trap_2,
i_datavalid,
i_readdata,
i_wait,
increment_cwp,
interrupt,
keep_pc,
load_nops,
pending_interrupt,
read_next,
reset_n,
save_status,
skip,
// outputs
ctrl_en,
cwp_is_hi_limit,
cwp_is_lo_limit,
d_address,
d_byteenable,
d_writedata,
decoded_instr,
i_address,
i_flush,
i_read,
ir,
ld,
next_is_ctrl_flow_instr,
next_is_restore,
next_is_save,
next_is_wrctl,
pfx,
RA,
restore,
save,
skp0,
skp1,
skprnz,
skprz,
skps,
st,
status_reg,
trap,
tret
);
parameter LOG_REGISTER_FILE_SIZE = 9;
parameter START_ADDRESS = 32'h8000;
parameter VECTOR_TABLE_ADDRESS = 32'h7780;
parameter FIFO_SIZE = 2;
input clk;
input current_reg_write_en;
input [5:0] d_irqnumber;
input [31:0] d_readdata;
input decrement_cwp;
input disable_interrupts;
input flush_pipeline;
input flush_fifo;
input force_interrupt;
input force_read;
input force_trap_1;
input force_trap_2;
input i_datavalid;
input [15:0] i_readdata;
input i_wait;
input increment_cwp;
input interrupt;
input keep_pc;
input load_nops;
input pending_interrupt;
input read_next;
input reset_n;
input save_status;
input skip;
output ctrl_en;
output cwp_is_hi_limit;
output cwp_is_lo_limit;
output [31:0] d_address;
output [3:0] d_byteenable;
output [31:0] d_writedata;
output [23:0] decoded_instr;
output [31:0] i_address;
output i_flush;
output i_read;
output [15:0] ir;
output ld;
output next_is_ctrl_flow_instr;
output next_is_restore;
output next_is_save;
output next_is_wrctl;
output pfx;
output [31:0] RA;
output restore;
output save;
output skp0;
output skp1;
output skprnz;
output skprz;
output skps;
output st;
output [17:0] status_reg;
output trap;
output tret;
wire [31:0] branch_logic_pc;
wire cpu_continue_running;
wire [31:0] current_reg_data_in;
wire [`LOG_REGISTER_FILE_SIZE-1:0] current_reg_write_address_in;
wire [4:0] cwp;
wire [4:0] cwp_for_check;
wire [4:0] cwp_minus_1;
wire fifo_datavalid;
wire flush_o_x;
wire [15:0] i_from_fifo;
wire [10:0] K;
wire next_is_trap;
wire next_is_tret;
wire s2_ctrl_flow_instr;
wire [23:0] s2_decoded_instr;
wire [15:0] s2_ir;
wire [`LOG_REGISTER_FILE_SIZE-1:0] s2_reg_a_address;
wire [31:0] s2_reg_a_data_out;
wire [`LOG_REGISTER_FILE_SIZE-1:0] s2_reg_b_address;
wire [31:0] s2_reg_b_data_out;
wire [`LOG_REGISTER_FILE_SIZE-1:0] s2_reg_write_address_out;
wire s3_ctrl_flow_instr;
wire [3:0] s3_ctrl_reg_address;
wire [23:0] s3_decoded_instr;
wire [15:0] s3_ir;
wire [31:0] s3_mux_a_data_out;
wire [31:0] s3_mux_b_data_out;
wire [31:0] s3_npc;
wire [31:0] s3_pc;
wire [31:0] s3_pc_plus_4;
wire [`LOG_REGISTER_FILE_SIZE-1:0] s3_reg_a_address;
wire [`LOG_REGISTER_FILE_SIZE-1:0] s3_reg_b_address;
wire [31:0] s3_reg_a_data_out;
wire [31:0] s3_reg_b_data_out;
wire [`LOG_REGISTER_FILE_SIZE-1:0] s3_reg_write_address_out;
wire [3:0] s4_ctrl_reg_address;
wire [23:0] s4_decoded_instr;
wire [15:0] s4_ir;
wire [31:0] s4_mux_a_data_out;
wire [31:0] s4_mux_b_data_out;
wire [31:0] s4_npc;
wire [31:0] s4_pc;
wire [31:0] s4_pc_plus_4;
wire [31:0] s4_reg_a_data_out;
wire [31:0] s4_reg_b_data_out;
wire [`LOG_REGISTER_FILE_SIZE-1:0] s4_reg_write_address_out;
wire s4_trap;
wire s4_tret;
wire [9:0] wvalid_for_check;
// cpu_continue_running is the opposite of stall signal (which does not really exist)
// The execution continues normally, as long as the control unit confirms that the current
// instruction has been executed, and the new one should be read (read_next), new instruction
// is actually available from the fifo (fifo_datavalid), and the fifo is not being flushed
// by the control-flow instruction
assign cpu_continue_running = read_next & fifo_datavalid & ~flush_fifo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -