blob: 2d0121e6ba9c61ec44db5bad17d42667c58e5928 [file] [log] [blame]
//-----------------------------------------------------------------------------
// @file wb_staging.vhd
//
// @brief Register wishbone signals.
//
// @details This logic create a holding FF for Wishbone interface.
// This is usefull to break timing issue at interconnect
//
// @author Sukru Uzun <sukru.uzun@procenne.com>
// @date 10.03.2022
//
// @todo
// @warning
//
// @project https://github.com/Procenne-Digital-Design/secure-memory.git
//
// @revision :
// 0.1 - 10 March 2022, Sukru Uzun
// initial version
//-----------------------------------------------------------------------------
module wb_stagging (
input logic clk_i,
input logic rst_n,
// WishBone Input master I/P
input logic [31:0] m_wbd_dat_i,
input logic [31:0] m_wbd_adr_i,
input logic [3:0] m_wbd_sel_i,
input logic m_wbd_we_i,
input logic m_wbd_cyc_i,
input logic m_wbd_stb_i,
input logic [3:0] m_wbd_tid_i,
output logic [31:0] m_wbd_dat_o,
output logic m_wbd_ack_o,
output logic m_wbd_err_o,
// Slave Interface
input logic [31:0] s_wbd_dat_i,
input logic s_wbd_ack_i,
input logic s_wbd_err_i,
output logic [31:0] s_wbd_dat_o,
output logic [31:0] s_wbd_adr_o,
output logic [3:0] s_wbd_sel_o,
output logic s_wbd_we_o,
output logic s_wbd_cyc_o,
output logic s_wbd_stb_o,
output logic [3:0] s_wbd_tid_o
);
logic holding_busy ; // Indicate Stagging for Free or not
logic [31:0] m_wbd_dat_i_ff ; // Flopped vesion of m_wbd_dat_i
logic [31:0] m_wbd_adr_i_ff ; // Flopped vesion of m_wbd_adr_i
logic [3:0] m_wbd_sel_i_ff ; // Flopped vesion of m_wbd_sel_i
logic m_wbd_we_i_ff ; // Flopped vesion of m_wbd_we_i
logic m_wbd_cyc_i_ff ; // Flopped vesion of m_wbd_cyc_i
logic m_wbd_stb_i_ff ; // Flopped vesion of m_wbd_stb_i
logic [3:0] m_wbd_tid_i_ff ; // Flopped vesion of m_wbd_tid_i
logic [31:0] s_wbd_dat_i_ff ; // Flopped vesion of s_wbd_dat_i
logic s_wbd_ack_i_ff ; // Flopped vesion of s_wbd_ack_i
logic s_wbd_err_i_ff ; // Flopped vesion of s_wbd_err_i
assign s_wbd_dat_o = m_wbd_dat_i_ff;
assign s_wbd_adr_o = m_wbd_adr_i_ff;
assign s_wbd_sel_o = m_wbd_sel_i_ff;
assign s_wbd_we_o = m_wbd_we_i_ff;
assign s_wbd_cyc_o = m_wbd_cyc_i_ff;
assign s_wbd_stb_o = m_wbd_stb_i_ff;
assign s_wbd_tid_o = m_wbd_tid_i_ff;
assign m_wbd_dat_o = s_wbd_dat_i_ff;
assign m_wbd_ack_o = s_wbd_ack_i_ff;
assign m_wbd_err_o = s_wbd_err_i_ff;
always @(negedge rst_n or posedge clk_i)
begin
if(rst_n == 1'b0) begin
holding_busy <= 1'b0;
m_wbd_dat_i_ff <= 'h0;
m_wbd_adr_i_ff <= 'h0;
m_wbd_sel_i_ff <= 'h0;
m_wbd_we_i_ff <= 'h0;
m_wbd_cyc_i_ff <= 'h0;
m_wbd_stb_i_ff <= 'h0;
m_wbd_tid_i_ff <= 'h0;
s_wbd_dat_i_ff <= 'h0;
s_wbd_ack_i_ff <= 'h0;
s_wbd_err_i_ff <= 'h0;
end else begin
s_wbd_dat_i_ff <= s_wbd_dat_i;
s_wbd_ack_i_ff <= s_wbd_ack_i;
s_wbd_err_i_ff <= s_wbd_err_i;
if(m_wbd_stb_i && holding_busy == 0 && m_wbd_ack_o == 0) begin
holding_busy <= 1'b1;
m_wbd_dat_i_ff <= m_wbd_dat_i;
m_wbd_adr_i_ff <= m_wbd_adr_i;
m_wbd_sel_i_ff <= m_wbd_sel_i;
m_wbd_we_i_ff <= m_wbd_we_i;
m_wbd_cyc_i_ff <= m_wbd_cyc_i;
m_wbd_stb_i_ff <= m_wbd_stb_i;
m_wbd_tid_i_ff <= m_wbd_tid_i;
end
else if (holding_busy && s_wbd_ack_i) begin
holding_busy <= 1'b0;
m_wbd_dat_i_ff <= 'h0;
m_wbd_adr_i_ff <= 'h0;
m_wbd_sel_i_ff <= 'h0;
m_wbd_we_i_ff <= 'h0;
m_wbd_cyc_i_ff <= 'h0;
m_wbd_stb_i_ff <= 'h0;
m_wbd_tid_i_ff <= 'h0;
end
end
end
endmodule