| // ========== Copyright Header Begin ========================================== |
| // |
| // OpenSPARC T1 Processor File: lsu_stb_rwdp.v |
| // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
| // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
| // |
| // The above named program is free software; you can redistribute it and/or |
| // modify it under the terms of the GNU General Public |
| // License version 2 as published by the Free Software Foundation. |
| // |
| // The above named program is distributed in the hope that it will be |
| // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| // General Public License for more details. |
| // |
| // You should have received a copy of the GNU General Public |
| // License along with this work; if not, write to the Free Software |
| // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
| // |
| // ========== Copyright Header End ============================================ |
| /////////////////////////////////////////////////////////////////// |
| /* |
| // Description: Datapath for STB |
| // - Mainly for formatting stb data |
| */ |
| //////////////////////////////////////////////////////////////////////// |
| // Global header file includes |
| //////////////////////////////////////////////////////////////////////// |
| `include "sys.h" // system level definition file which contains the |
| // time scale definition |
| |
| `include "iop.h" |
| |
| //////////////////////////////////////////////////////////////////////// |
| // Local header file includes / local defines |
| //////////////////////////////////////////////////////////////////////// |
| |
| module lsu_stb_rwdp (/*AUTOARG*/ |
| // Outputs |
| so, stb_rdata_ramd_buf, stb_rdata_ramd_b74_buf, lsu_stb_st_data_g, |
| // Inputs |
| rclk, si, se, rst_tri_en, exu_lsu_rs3_data_e, |
| lsu_stb_data_early_sel_e, lsu_stb_data_final_sel_m, |
| exu_lsu_rs2_data_e, lsu_st_sz_bhww_m, lsu_st_sz_dw_m, |
| lsu_st_sz_bhw_m, lsu_st_sz_wdw_m, lsu_st_sz_b_m, lsu_st_sz_w_m, |
| lsu_st_sz_hw_m, lsu_st_sz_hww_m, ffu_lsu_data, lsu_st_hw_le_g, |
| lsu_st_w_or_dbl_le_g, lsu_st_x_le_g, lsu_swap_sel_default_g, |
| lsu_swap_sel_default_byte_7_2_g, stb_rdata_ramd, |
| stb_rdata_ramd_b74 |
| ) ; |
| |
| input rclk ; |
| input si; |
| output so; |
| input se; |
| input rst_tri_en; |
| |
| input [63:0] exu_lsu_rs3_data_e ; // data for store. |
| input [3:0] lsu_stb_data_early_sel_e ;// early source of data for stb |
| input lsu_stb_data_final_sel_m ;// early source of data for stb |
| input [63:0] exu_lsu_rs2_data_e ; // rs2 data for cas. |
| input lsu_st_sz_bhww_m ; // byte or hword or word |
| input lsu_st_sz_dw_m ; // double word |
| input lsu_st_sz_bhw_m ; // byte or hword |
| input lsu_st_sz_wdw_m ; // word or dword |
| input lsu_st_sz_b_m ; // byte |
| input lsu_st_sz_w_m ; // word |
| input lsu_st_sz_hw_m ; // hword |
| input lsu_st_sz_hww_m ; // hword or word |
| input [63:0] ffu_lsu_data ; // fp store data - m stage |
| //input lsu_bendian_access_g ; // bendian st |
| //input lsu_stdbl_inst_m ; // stdbl |
| |
| input lsu_st_hw_le_g; |
| input lsu_st_w_or_dbl_le_g; |
| input lsu_st_x_le_g; |
| input lsu_swap_sel_default_g; |
| input lsu_swap_sel_default_byte_7_2_g; |
| |
| input [69:0] stb_rdata_ramd; |
| input stb_rdata_ramd_b74; |
| |
| output [69:0] stb_rdata_ramd_buf; |
| output stb_rdata_ramd_b74_buf; |
| |
| output [63:0] lsu_stb_st_data_g ; // data to be written to stb |
| |
| wire [7:0] byte0, byte1, byte2, byte3 ; |
| wire [7:0] byte4, byte5, byte6, byte7 ; |
| wire [7:0] swap_byte0, swap_byte1, swap_byte2, swap_byte3 ; |
| wire [7:0] swap_byte4, swap_byte5, swap_byte6, swap_byte7 ; |
| |
| wire [63:0] stb_st_data_g ; |
| wire [63:0] stb_st_data_early_e ; |
| wire [63:0] stb_st_data_early_m ; |
| wire [63:0] stb_st_data_final_m ; |
| wire st_sz_bhww_g ; |
| wire st_sz_dw_g ; |
| wire st_sz_bhw_g ; |
| wire st_sz_wdw_g ; |
| wire st_sz_b_g ; |
| wire st_sz_w_g ; |
| wire st_sz_hw_g ; |
| wire st_sz_hww_g ; |
| //wire bendian ; |
| //wire stdbl_g ; |
| |
| wire clk; |
| assign clk = rclk; |
| |
| //assign stb_st_data_early_e[63:0] = //@@ bw_u1_muxi41d_2x |
| // lsu_stb_data_early_sel_e[0] ? 64'hffff_ffff_ffff_ffff : // ldstub writes all ones |
| // lsu_stb_data_early_sel_e[1] ? exu_lsu_rs2_data_e[63:0] : // cas pkt1 uses rs2 |
| // lsu_stb_data_early_sel_e[2] ? exu_lsu_rs3_data_e[63:0] : // use rs3/rd data. |
| // lsu_stb_data_early_sel_e[3] ? {exu_lsu_rs2_data_e[31:0],exu_lsu_rs3_data_e[31:0]} : |
| // else std non-alt |
| // 64'hxxxx_xxxx_xxxx_xxxx ; |
| |
| mux4ds #(64) stb_st_data_early_e_mx ( |
| .in0 (64'hffff_ffff_ffff_ffff), |
| .in1 (exu_lsu_rs2_data_e[63:0]), |
| .in2 (exu_lsu_rs3_data_e[63:0]), |
| .in3 ({exu_lsu_rs2_data_e[31:0],exu_lsu_rs3_data_e[31:0]}), |
| .sel0(lsu_stb_data_early_sel_e[0]), |
| .sel1(lsu_stb_data_early_sel_e[1]), |
| .sel2(lsu_stb_data_early_sel_e[2]), |
| .sel3(lsu_stb_data_early_sel_e[3]), |
| .dout(stb_st_data_early_e[63:0])); |
| |
| |
| // Stage early data to m |
| dff_s #(64) stgm_rs2 ( //@@ bw_u1_soffi_2x |
| .din (stb_st_data_early_e[63:0]), |
| .q (stb_st_data_early_m[63:0]), |
| .clk (clk), |
| .se (se), .si (), .so () |
| ); |
| |
| assign stb_st_data_final_m[63:0] = //@@ bw_u1_muxi21_2x |
| lsu_stb_data_final_sel_m ? stb_st_data_early_m[63:0] : ffu_lsu_data[63:0] ; // mux in fpst data |
| |
| // Precursor of data to be stored in stb |
| // For ldstub, all one's need to be written to stb. |
| // For cas/swap, data remains unmodified. |
| // Stage final data to g |
| dff_s #(64) stgg_rs2 ( //@@ bw_u1_soffi_2x |
| .din (stb_st_data_final_m[63:0]), |
| .q (stb_st_data_g[63:0]), |
| .clk (clk), |
| .se (se), .si (), .so () |
| ); |
| |
| dff_s #(8) stgm_sel ( //@@ bw_u1_soff_8x |
| .din ({lsu_st_sz_bhww_m,lsu_st_sz_dw_m,lsu_st_sz_bhw_m,lsu_st_sz_wdw_m, |
| lsu_st_sz_b_m,lsu_st_sz_w_m,lsu_st_sz_hw_m,lsu_st_sz_hww_m}), |
| .q ({st_sz_bhww_g,st_sz_dw_g,st_sz_bhw_g,st_sz_wdw_g, |
| st_sz_b_g,st_sz_w_g,st_sz_hw_g,st_sz_hww_g}), |
| .clk (clk), |
| .se (se), .si (), .so () |
| ); |
| |
| // Now format data for st data. |
| assign byte0[7:0] = stb_st_data_g[7:0] ; //@@ PASS |
| assign byte1[7:0] = stb_st_data_g[15:8] ; //@@ PASS |
| assign byte2[7:0] = stb_st_data_g[23:16] ; //@@ PASS |
| assign byte3[7:0] = stb_st_data_g[31:24] ; //@@ PASS |
| assign byte4[7:0] = stb_st_data_g[39:32] ; //@@ PASS |
| assign byte5[7:0] = stb_st_data_g[47:40] ; //@@ PASS |
| assign byte6[7:0] = stb_st_data_g[55:48] ; //@@ PASS |
| assign byte7[7:0] = stb_st_data_g[63:56] ; //@@ PASS |
| |
| |
| //assign bendian = lsu_bendian_access_g ; // bendian store |
| |
| // Control needs to move to lsu_stb_rwctl once this is fully tested. |
| |
| // First do swap for big-endian vs little-endian case. |
| |
| //wire swap_sel_default ; |
| |
| //assign swap_sel_default = bendian | (~bendian & st_sz_b_g) ; |
| |
| // swap byte0 |
| //assign swap_byte0[7:0] = //@@ bw_u1_muxi41d_4x |
| // lsu_swap_sel_default_g ? byte0[7:0] : |
| // lsu_st_hw_le_g ? byte1[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte3[7:0] : |
| // lsu_st_x_le_g ? byte7[7:0] : 8'bxxxx_xxxx ; |
| |
| mux4ds #(8) swap_byte0_mx ( |
| .in0 (byte0[7:0]), .sel0(lsu_swap_sel_default_g), |
| .in1 (byte1[7:0]), .sel1(lsu_st_hw_le_g), |
| .in2 (byte3[7:0]), .sel2(lsu_st_w_or_dbl_le_g), |
| .in3 (byte7[7:0]), .sel3(lsu_st_x_le_g), |
| .dout(swap_byte0[7:0])); |
| |
| // swap byte1 |
| //assign swap_byte1[7:0] = //@@ bw_u1_muxi41d_4x |
| // lsu_swap_sel_default_g ? byte1[7:0] : |
| // lsu_st_hw_le_g ? byte0[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte2[7:0] : |
| // lsu_st_x_le_g ? byte6[7:0] : 8'bxxxx_xxxx ; |
| |
| mux4ds #(8) swap_byte1_mx ( |
| .in0 (byte1[7:0]), .sel0(lsu_swap_sel_default_g), |
| .in1 (byte0[7:0]), .sel1(lsu_st_hw_le_g), |
| .in2 (byte2[7:0]), .sel2(lsu_st_w_or_dbl_le_g), |
| .in3 (byte6[7:0]), .sel3(lsu_st_x_le_g), |
| .dout (swap_byte1[7:0])); |
| |
| // swap byte2 |
| //assign swap_byte2[7:0] = //@@ bw_u1_muxi31d_4x |
| // lsu_swap_sel_default_g ? byte2[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte1[7:0] : |
| // lsu_st_x_le_g ? byte5[7:0] : 8'bxxxx_xxxx ; |
| |
| mux3ds #(8) swap_byte2_mx ( |
| .in0 (byte2[7:0]), .sel0(lsu_swap_sel_default_byte_7_2_g), |
| .in1 (byte1[7:0]), .sel1(lsu_st_w_or_dbl_le_g), |
| .in2 (byte5[7:0]), .sel2(lsu_st_x_le_g), |
| .dout (swap_byte2[7:0])); |
| |
| // swap byte3 |
| //assign swap_byte3[7:0] = //@@ bw_u1_muxi31d_4x |
| // lsu_swap_sel_default_g ? byte3[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte0[7:0] : |
| // lsu_st_x_le_g ? byte4[7:0] : 8'bxxxx_xxxx ; |
| |
| mux3ds #(8) swap_byte3_mx ( |
| .in0 (byte3[7:0]), .sel0(lsu_swap_sel_default_byte_7_2_g), |
| .in1 (byte0[7:0]), .sel1(lsu_st_w_or_dbl_le_g), |
| .in2 (byte4[7:0]), .sel2(lsu_st_x_le_g), |
| .dout(swap_byte3[7:0])); |
| |
| // swap byte4 |
| //assign swap_byte4[7:0] = //@@ bw_u1_muxi31d_4x |
| // lsu_swap_sel_default_g ? byte4[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte7[7:0] : |
| // lsu_st_x_le_g ? byte3[7:0] : 8'bxxxx_xxxx ; |
| |
| mux3ds #(8) swap_byte4_mx ( |
| .in0 (byte4[7:0]), .sel0(lsu_swap_sel_default_byte_7_2_g), |
| .in1 (byte7[7:0]), .sel1(lsu_st_w_or_dbl_le_g), |
| .in2 (byte3[7:0]), .sel2(lsu_st_x_le_g), |
| .dout(swap_byte4[7:0])); |
| |
| // swap byte5 |
| //assign swap_byte5[7:0] = //@@ bw_u1_muxi31d_4x |
| // lsu_swap_sel_default_g ? byte5[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte6[7:0] : |
| // lsu_st_x_le_g ? byte2[7:0] : 8'bxxxx_xxxx ; |
| |
| mux3ds #(8) swap_byte5_mx ( |
| .in0 (byte5[7:0]), .sel0(lsu_swap_sel_default_byte_7_2_g), |
| .in1 (byte6[7:0]), .sel1(lsu_st_w_or_dbl_le_g), |
| .in2 (byte2[7:0]), .sel2(lsu_st_x_le_g), |
| .dout(swap_byte5[7:0])); |
| |
| // swap byte6 |
| //assign swap_byte6[7:0] = //@@ bw_u1_muxi31d_4x |
| // lsu_swap_sel_default_g ? byte6[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte5[7:0] : |
| // lsu_st_x_le_g ? byte1[7:0] : 8'bxxxx_xxxx ; |
| |
| mux3ds #(8) swap_byte6_mx ( |
| .in0 (byte6[7:0]), .sel0 (lsu_swap_sel_default_byte_7_2_g), |
| .in1 (byte5[7:0]), .sel1 (lsu_st_w_or_dbl_le_g), |
| .in2 (byte1[7:0]), .sel2 (lsu_st_x_le_g), |
| .dout(swap_byte6[7:0])); |
| |
| // swap byte7 |
| //assign swap_byte7[7:0] = //@@ bw_u1_muxi31d_4x |
| // lsu_swap_sel_default_g ? byte7[7:0] : |
| // lsu_st_w_or_dbl_le_g ? byte4[7:0] : |
| // lsu_st_x_le_g ? byte0[7:0] : 8'bxxxx_xxxx ; |
| |
| mux3ds #(8) swap_byte7_mx ( |
| .in0 (byte7[7:0]), .sel0 (lsu_swap_sel_default_byte_7_2_g), |
| .in1 (byte4[7:0]), .sel1 (lsu_st_w_or_dbl_le_g), |
| .in2 (byte0[7:0]), .sel2 (lsu_st_x_le_g), |
| .dout (swap_byte7[7:0])); |
| |
| // Now replicate date across 8 bytes. |
| |
| // replicated byte0 |
| assign lsu_stb_st_data_g[7:0] = swap_byte0[7:0] ; // all data sizes //@@ bw_u1_inv_8x |
| |
| // replicated byte1 |
| assign lsu_stb_st_data_g[15:8] = //@@ bw_u1_muxi21_6x |
| st_sz_b_g ? swap_byte0[7:0] : swap_byte1[7:0] ; |
| |
| // replicated byte2 |
| assign lsu_stb_st_data_g[23:16] = //@@ bw_u1_muxi21_6x |
| st_sz_bhw_g ? swap_byte0[7:0] : swap_byte2[7:0] ; |
| |
| // replicated byte3 |
| //assign lsu_stb_st_data_g[31:24] = //@@ bw_u1_muxi31d_6x |
| // st_sz_b_g ? swap_byte0 : // swap_byte |
| // st_sz_hw_g ? swap_byte1 : // hword |
| // st_sz_wdw_g ? swap_byte3 : // dword or word |
| // 8'bxxxx_xxxx ; |
| |
| wire st_sz_b_g_sel, st_sz_hw_g_sel, st_sz_wdw_g_sel; |
| assign st_sz_b_g_sel = st_sz_b_g & ~rst_tri_en; |
| assign st_sz_hw_g_sel = st_sz_hw_g & ~rst_tri_en; |
| assign st_sz_wdw_g_sel = st_sz_wdw_g | rst_tri_en; |
| |
| mux3ds #(8) rpl_byte3_mx ( |
| .in0 (swap_byte0[7:0]), .sel0 (st_sz_b_g_sel), |
| .in1 (swap_byte1[7:0]), .sel1 (st_sz_hw_g_sel), |
| .in2 (swap_byte3[7:0]), .sel2 (st_sz_wdw_g_sel), |
| .dout (lsu_stb_st_data_g[31:24])); |
| |
| // replicated byte4 |
| assign lsu_stb_st_data_g[39:32] = //@@ bw_u1_muxi21_6x |
| st_sz_bhww_g ? swap_byte0[7:0] : swap_byte4[7:0] ; // dword |
| |
| |
| // replicated byte5 |
| //assign lsu_stb_st_data_g[47:40] = //@@ bw_u1_muxi31d_6x |
| // st_sz_b_g ? swap_byte0 : // swap_byte |
| // st_sz_hww_g ? swap_byte1 : // hword or word |
| // st_sz_dw_g ? swap_byte5 : // dword |
| // 8'bxxxx_xxxx ; |
| |
| wire st_sz_hww_g_sel, st_sz_dw_g_sel; |
| assign st_sz_hww_g_sel = st_sz_hww_g & ~rst_tri_en; |
| assign st_sz_dw_g_sel = st_sz_dw_g | rst_tri_en; |
| |
| mux3ds #(8) rpl_byte5_mx ( |
| .in0 (swap_byte0[7:0]), .sel0(st_sz_b_g_sel), |
| .in1 (swap_byte1[7:0]), .sel1(st_sz_hww_g_sel), |
| .in2 (swap_byte5[7:0]), .sel2(st_sz_dw_g_sel), |
| .dout(lsu_stb_st_data_g[47:40])); |
| |
| // replicated byte6 |
| //assign lsu_stb_st_data_g[55:48] = //@@ bw_u1_muxi31d_6x |
| // st_sz_bhw_g ? swap_byte0 : // swap_byte or hword |
| // st_sz_w_g ? swap_byte2 : // word |
| // st_sz_wdw_g ? swap_byte6 : // dword |
| // 8'bxxxx_xxxx ; |
| |
| wire st_sz_bhw_g_sel, st_sz_w_g_sel; |
| assign st_sz_bhw_g_sel = st_sz_bhw_g & ~rst_tri_en; |
| assign st_sz_w_g_sel = st_sz_w_g & ~rst_tri_en; |
| |
| |
| mux3ds #(8) rpl_byte6_mx ( |
| .in0 (swap_byte0[7:0]), |
| .in1 (swap_byte2[7:0]), |
| .in2 (swap_byte6[7:0]), |
| .sel0(st_sz_bhw_g_sel), |
| .sel1(st_sz_w_g_sel), |
| .sel2(st_sz_dw_g_sel), |
| .dout(lsu_stb_st_data_g[55:48])); |
| |
| // replicated byte7 |
| //assign lsu_stb_st_data_g[63:56] = //@@ bw_u1_muxi41d_6x |
| // st_sz_b_g ? swap_byte0 : // swap_byte |
| // st_sz_hw_g ? swap_byte1 : // hword |
| // st_sz_w_g ? swap_byte3 : // word |
| // st_sz_dw_g ? swap_byte7 : // dword |
| // 8'bxxxx_xxxx ; |
| |
| mux4ds #(8) rpl_byte7_mx ( |
| .in0(swap_byte0[7:0]), .sel0(st_sz_b_g_sel), |
| .in1(swap_byte1[7:0]), .sel1(st_sz_hw_g_sel), |
| .in2(swap_byte3[7:0]), .sel2(st_sz_w_g_sel), |
| .in3(swap_byte7[7:0]), .sel3(st_sz_dw_g_sel), |
| .dout (lsu_stb_st_data_g[63:56])); |
| |
| //========================================================= |
| //stb rdata buffer |
| assign stb_rdata_ramd_buf[69:0] = stb_rdata_ramd[69:0]; |
| assign stb_rdata_ramd_b74_buf = stb_rdata_ramd_b74; |
| |
| endmodule |