URL
https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk
Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc
[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [mor1kx-5.0/] [rtl/] [verilog/] [mor1kx_execute_ctrl_cappuccino.v] - Rev 48
Compare with Previous | Blame | View Log
/* **************************************************************************** This Source Code Form is subject to the terms of the Open Hardware Description License, v. 1.0. If a copy of the OHDL was not distributed with this file, You can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt Description: execute to control stage signal passing Generate valid signal when stage is done Copyright (C) 2012 Authors Author(s): Julius Baxter <juliusbaxter@gmail.com> Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> ***************************************************************************** */ `include "mor1kx-defines.v" module mor1kx_execute_ctrl_cappuccino #( parameter OPTION_OPERAND_WIDTH = 32, parameter OPTION_RESET_PC = {{(OPTION_OPERAND_WIDTH-13){1'b0}}, `OR1K_RESET_VECTOR,8'd0}, parameter OPTION_RF_ADDR_WIDTH = 5, parameter FEATURE_FPU = "NONE", // ENABLED|NONE parameter FEATURE_MULTIPLIER = "THREESTAGE" ) ( input clk, input rst, input padv_i, input padv_ctrl_i, input execute_except_ibus_err_i, input execute_except_itlb_miss_i, input execute_except_ipagefault_i, input execute_except_illegal_i, input execute_except_ibus_align_i, input execute_except_syscall_i, input lsu_except_dbus_i, input lsu_except_align_i, input lsu_except_dtlb_miss_i, input lsu_except_dpagefault_i, input execute_except_trap_i, input pipeline_flush_i, input op_mul_i, input op_lsu_load_i, input op_lsu_store_i, input op_lsu_atomic_i, input [1:0] lsu_length_i, input lsu_zext_i, input op_msync_i, input op_mfspr_i, input op_mtspr_i, input alu_valid_i, input lsu_valid_i, input msync_stall_i, input op_jr_i, input op_jal_i, input op_rfe_i, input [OPTION_OPERAND_WIDTH-1:0] alu_result_i, input [OPTION_OPERAND_WIDTH-1:0] adder_result_i, input [OPTION_OPERAND_WIDTH-1:0] rfb_i, input [OPTION_OPERAND_WIDTH-1:0] execute_jal_result_i, input flag_set_i, input flag_clear_i, input carry_set_i, input carry_clear_i, input overflow_set_i, input overflow_clear_i, input [`OR1K_FPCSR_WIDTH-1:0] fpcsr_i, input fpcsr_set_i, input [OPTION_OPERAND_WIDTH-1:0] pc_execute_i, input execute_rf_wb_i, output reg ctrl_rf_wb_o, output reg wb_rf_wb_o, // address of destination register from execute stage input [OPTION_RF_ADDR_WIDTH-1:0] execute_rfd_adr_i, output reg [OPTION_RF_ADDR_WIDTH-1:0] ctrl_rfd_adr_o, output reg [OPTION_RF_ADDR_WIDTH-1:0] wb_rfd_adr_o, input execute_bubble_i, // Input from control stage for mfspr/mtspr ack input ctrl_mfspr_ack_i, input ctrl_mtspr_ack_i, output reg [OPTION_OPERAND_WIDTH-1:0] ctrl_alu_result_o, output reg [OPTION_OPERAND_WIDTH-1:0] ctrl_lsu_adr_o, output reg [OPTION_OPERAND_WIDTH-1:0] ctrl_rfb_o, output reg ctrl_flag_set_o, output reg ctrl_flag_clear_o, output reg ctrl_carry_set_o, output reg ctrl_carry_clear_o, output reg ctrl_overflow_set_o, output reg ctrl_overflow_clear_o, output reg [`OR1K_FPCSR_WIDTH-1:0] ctrl_fpcsr_o, output reg ctrl_fpcsr_set_o, output reg [OPTION_OPERAND_WIDTH-1:0] pc_ctrl_o, output reg ctrl_op_mul_o, output reg ctrl_op_lsu_load_o, output reg ctrl_op_lsu_store_o, output reg ctrl_op_lsu_atomic_o, output reg [1:0] ctrl_lsu_length_o, output reg ctrl_lsu_zext_o, output reg ctrl_op_msync_o, output reg ctrl_op_mfspr_o, output reg ctrl_op_mtspr_o, output reg ctrl_op_rfe_o, output reg ctrl_except_ibus_err_o, output reg ctrl_except_itlb_miss_o, output reg ctrl_except_ipagefault_o, output reg ctrl_except_ibus_align_o, output reg ctrl_except_illegal_o, output reg ctrl_except_syscall_o, output reg ctrl_except_dbus_o, output reg ctrl_except_dtlb_miss_o, output reg ctrl_except_dpagefault_o, output reg ctrl_except_align_o, output reg ctrl_except_trap_o, output execute_valid_o, output ctrl_valid_o ); wire ctrl_stall; wire execute_stall; // LSU or MTSPR/MFSPR can stall from ctrl stage assign ctrl_stall = (ctrl_op_lsu_load_o | ctrl_op_lsu_store_o) & !lsu_valid_i | ctrl_op_msync_o & msync_stall_i | ctrl_op_mfspr_o & !ctrl_mfspr_ack_i | ctrl_op_mtspr_o & !ctrl_mtspr_ack_i; assign ctrl_valid_o = !ctrl_stall; // Execute stage can be stalled from ctrl stage and by ALU assign execute_stall = ctrl_stall | !alu_valid_i; assign execute_valid_o = !execute_stall; always @(posedge clk `OR_ASYNC_RST) if (rst) begin ctrl_except_ibus_err_o <= 0; ctrl_except_itlb_miss_o <= 0; ctrl_except_ipagefault_o <= 0; ctrl_except_ibus_align_o <= 0; ctrl_except_illegal_o <= 0; ctrl_except_syscall_o <= 0; ctrl_except_trap_o <= 0; ctrl_except_dbus_o <= 0; ctrl_except_align_o <= 0; end else if (pipeline_flush_i) begin ctrl_except_ibus_err_o <= 0; ctrl_except_itlb_miss_o <= 0; ctrl_except_ipagefault_o <= 0; ctrl_except_ibus_align_o <= 0; ctrl_except_illegal_o <= 0; ctrl_except_syscall_o <= 0; ctrl_except_trap_o <= 0; ctrl_except_dbus_o <= 0; ctrl_except_align_o <= 0; end else begin if (padv_i) begin ctrl_except_ibus_err_o <= execute_except_ibus_err_i; ctrl_except_itlb_miss_o <= execute_except_itlb_miss_i; ctrl_except_ipagefault_o <= execute_except_ipagefault_i; ctrl_except_ibus_align_o <= execute_except_ibus_align_i; ctrl_except_illegal_o <= execute_except_illegal_i; ctrl_except_syscall_o <= execute_except_syscall_i; ctrl_except_trap_o <= execute_except_trap_i; end ctrl_except_dbus_o <= lsu_except_dbus_i; ctrl_except_align_o <= lsu_except_align_i; ctrl_except_dtlb_miss_o <= lsu_except_dtlb_miss_i; ctrl_except_dpagefault_o <= lsu_except_dpagefault_i; end always @(posedge clk) if (padv_i) if (op_jal_i) ctrl_alu_result_o <= execute_jal_result_i; else ctrl_alu_result_o <= alu_result_i; always @(posedge clk) if (padv_i & (op_lsu_store_i | op_lsu_load_i)) ctrl_lsu_adr_o <= adder_result_i; always @(posedge clk) if (padv_i) ctrl_rfb_o <= rfb_i; always @(posedge clk `OR_ASYNC_RST) if (rst) begin ctrl_flag_set_o <= 0; ctrl_flag_clear_o <= 0; ctrl_carry_set_o <= 0; ctrl_carry_clear_o <= 0; ctrl_overflow_set_o <= 0; ctrl_overflow_clear_o <= 0; end else if (padv_i) begin ctrl_flag_set_o <= flag_set_i; ctrl_flag_clear_o <= flag_clear_i; ctrl_carry_set_o <= carry_set_i; ctrl_carry_clear_o <= carry_clear_i; ctrl_overflow_set_o <= overflow_set_i; ctrl_overflow_clear_o <= overflow_clear_i; end // pc_ctrl should not advance when a nop bubble moves from execute to // ctrl/mem stage always @(posedge clk `OR_ASYNC_RST) if (rst) pc_ctrl_o <= OPTION_RESET_PC; else if (padv_i & !execute_bubble_i) pc_ctrl_o <= pc_execute_i; // // The pipeline flush comes when the instruction that has caused // an exception or the instruction that has been interrupted is in // ctrl stage, so the padv_execute signal has to have higher prioity // than the pipeline flush in order to not accidently kill a valid // instruction coming in from execute stage. // generate if (FEATURE_MULTIPLIER=="PIPELINED") begin always @(posedge clk `OR_ASYNC_RST) if (rst) ctrl_op_mul_o <= 0; else if (padv_i) ctrl_op_mul_o <= op_mul_i; else if (pipeline_flush_i) ctrl_op_mul_o <= 0; end else begin always @(posedge clk) ctrl_op_mul_o <= 0; end endgenerate // FPU related generate /* verilator lint_off WIDTH */ if (FEATURE_FPU!="NONE") begin : fpu_execute_ctrl_ena /* verilator lint_on WIDTH */ always @(posedge clk `OR_ASYNC_RST) begin if (rst) begin ctrl_fpcsr_o <= {`OR1K_FPCSR_WIDTH{1'b0}}; ctrl_fpcsr_set_o <= 0; end else if (pipeline_flush_i) begin ctrl_fpcsr_o <= {`OR1K_FPCSR_WIDTH{1'b0}}; ctrl_fpcsr_set_o <= 0; end else if (padv_i) begin ctrl_fpcsr_o <= fpcsr_i; ctrl_fpcsr_set_o <= fpcsr_set_i; end end // @clk end else begin : fpu_execute_ctrl_none always @(posedge clk `OR_ASYNC_RST) begin if (rst) begin ctrl_fpcsr_o <= {`OR1K_FPCSR_WIDTH{1'b0}}; ctrl_fpcsr_set_o <= 0; end end // @clk end endgenerate // FPU related always @(posedge clk `OR_ASYNC_RST) if (rst) begin ctrl_op_mfspr_o <= 0; ctrl_op_mtspr_o <= 0; end else if (padv_i) begin ctrl_op_mfspr_o <= op_mfspr_i; ctrl_op_mtspr_o <= op_mtspr_i; end else if (pipeline_flush_i) begin ctrl_op_mfspr_o <= 0; ctrl_op_mtspr_o <= 0; end always @(posedge clk `OR_ASYNC_RST) if (rst) ctrl_op_rfe_o <= 0; else if (padv_i) ctrl_op_rfe_o <= op_rfe_i; else if (pipeline_flush_i) ctrl_op_rfe_o <= 0; always @(posedge clk `OR_ASYNC_RST) if (rst) ctrl_op_msync_o <= 0; else if (padv_i) ctrl_op_msync_o <= op_msync_i; else if (pipeline_flush_i) ctrl_op_msync_o <= 0; always @(posedge clk `OR_ASYNC_RST) if (rst) begin ctrl_op_lsu_load_o <= 0; ctrl_op_lsu_store_o <= 0; ctrl_op_lsu_atomic_o <= 0; end else if (ctrl_except_align_o | ctrl_except_dbus_o | ctrl_except_dtlb_miss_o | ctrl_except_dpagefault_o) begin ctrl_op_lsu_load_o <= 0; ctrl_op_lsu_store_o <= 0; ctrl_op_lsu_atomic_o <= 0; end else if (padv_i) begin ctrl_op_lsu_load_o <= op_lsu_load_i; ctrl_op_lsu_store_o <= op_lsu_store_i; ctrl_op_lsu_atomic_o <= op_lsu_atomic_i; end else if (pipeline_flush_i) begin ctrl_op_lsu_load_o <= 0; ctrl_op_lsu_store_o <= 0; ctrl_op_lsu_atomic_o <= 0; end always @(posedge clk) if (padv_i) begin ctrl_lsu_length_o <= lsu_length_i; ctrl_lsu_zext_o <= lsu_zext_i; end always @(posedge clk `OR_ASYNC_RST) if (rst) ctrl_rf_wb_o <= 0; else if (padv_i) ctrl_rf_wb_o <= execute_rf_wb_i; else if (ctrl_op_mfspr_o & ctrl_mfspr_ack_i | ctrl_op_lsu_load_o & lsu_valid_i) // Deassert the write enable when the "bus" access is done, to avoid: // 1) Writing multiple times to RF // 2) Signaling a need to bypass from control stage, when it really // should be a bypass from wb stage. ctrl_rf_wb_o <= 0; else if (pipeline_flush_i) ctrl_rf_wb_o <= 0; always @(posedge clk) if (padv_i) ctrl_rfd_adr_o <= execute_rfd_adr_i; // load and mfpsr can stall from ctrl stage, so we have to hold off the // write back on them always @(posedge clk `OR_ASYNC_RST) if (rst) wb_rf_wb_o <= 0; else if (pipeline_flush_i) wb_rf_wb_o <= 0; else if (ctrl_op_mfspr_o) wb_rf_wb_o <= ctrl_rf_wb_o & ctrl_mfspr_ack_i; else if (ctrl_op_lsu_load_o) wb_rf_wb_o <= ctrl_rf_wb_o & lsu_valid_i; else wb_rf_wb_o <= ctrl_rf_wb_o & padv_ctrl_i; always @(posedge clk) wb_rfd_adr_o <= ctrl_rfd_adr_o; endmodule // mor1kx_execute_ctrl_cappuccino