OpenCores
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-3.1/] [rtl/] [verilog/] [mor1kx_execute_ctrl_cappuccino.v] - Rev 38

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_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_mfspr_i,
    input 				  op_mtspr_i,
    input 				  alu_valid_i,
    input 				  lsu_valid_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 [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 [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_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_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
 
   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) 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 | 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
 

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.