// © IBM Corp. 2020 // Licensed under the Apache License, Version 2.0 (the "License"), as modified by // the terms below; you may not use the files in this repository except in // compliance with the License as modified. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // // Modified Terms: // // 1) For the purpose of the patent license granted to you in Section 3 of the // License, the "Work" hereby includes implementations of the work of authorship // in physical form. // // 2) Notwithstanding any terms to the contrary in the License, any licenses // necessary for implementation of the Work that are available from OpenPOWER // via the Power ISA End User License Agreement (EULA) are explicitly excluded // hereunder, and may be obtained from OpenPOWER under the terms and conditions // of the EULA. // // Unless required by applicable law or agreed to in writing, the reference design // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License // for the specific language governing permissions and limitations under the License. // // Additional rights, including the ability to physically implement a softcore that // is compliant with the required sections of the Power ISA Specification, are // available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be // obtained (along with the Power ISA) here: https://openpowerfoundation.org. `timescale 1 ns / 1 ns // // Description: XU LSU Load Data Rotator //***************************************************************************** // ########################################################################################## // Contents // 1) 16 bit Unaligned Rotate to the Right Rotator // 2) Algebraic Sign Extension support // 3) Little/Big Endian Support // ########################################################################################## `include "tri_a2o.vh" module tri_rot16s_ru( opsize, le, le_rotate_sel, be_rotate_sel, algebraic, le_algebraic_sel, be_algebraic_sel, arr_data, stq7_byp_val, stq_byp_val, stq7_rmw_data, stq8_rmw_data, data_latched, data_rot, algebraic_bit, nclk, vdd, gnd, delay_lclkr_dc, mpw1_dc_b, mpw2_dc_b, func_sl_force, func_sl_thold_0_b, sg_0, act, scan_in, scan_out ); input [0:4] opsize; // (0)16B (1)8B (2)4B (3)2B (4)1B input le; input [0:3] le_rotate_sel; input [0:3] be_rotate_sel; input algebraic; input [0:3] le_algebraic_sel; input [0:3] be_algebraic_sel; input [0:15] arr_data; // data to rotate input stq7_byp_val; input stq_byp_val; input [0:15] stq7_rmw_data; input [0:15] stq8_rmw_data; output [0:15] data_latched; // latched data, not rotated output [0:15] data_rot; // rotated data out output [0:5] algebraic_bit; (* pin_data="PIN_FUNCTION=/G_CLK/CAP_LIMIT=/99999/" *) input [0:`NCLK_WIDTH-1] nclk; inout vdd; inout gnd; input delay_lclkr_dc; input mpw1_dc_b; input mpw2_dc_b; input func_sl_force; input func_sl_thold_0_b; input sg_0; input act; (* pin_data="PIN_FUNCTION=/SCAN_IN/" *) input scan_in; (* pin_data="PIN_FUNCTION=/SCAN_OUT/" *) output scan_out; // tri_rot16s_ru wire my_d1clk; wire my_d2clk; wire [0:`NCLK_WIDTH-1] my_lclk; wire [0:15] data_latched_b; wire [0:0] bele_gp0_q_b; wire [0:0] bele_gp0_q; wire [0:0] bele_gp0_din; wire [0:3] be_shx04_gp0_q_b; wire [0:3] be_shx04_gp0_q; wire [0:3] be_shx04_gp0_din; wire [0:3] le_shx04_gp0_q_b; wire [0:3] le_shx04_gp0_q; wire [0:3] le_shx04_gp0_din; wire [0:3] be_shx01_gp0_q_b; wire [0:3] be_shx01_gp0_q; wire [0:3] be_shx01_gp0_din; wire [0:3] le_shx01_gp0_q_b; wire [0:3] le_shx01_gp0_q; wire [0:3] le_shx01_gp0_din; wire [0:4] mask_q_b; wire [0:4] mask_q; wire [0:4] mask_din; wire [0:3] be_shx04_sgn0_q_b; wire [0:3] be_shx04_sgn0_q; wire [0:3] be_shx04_sgn0_din; wire [0:3] le_shx04_sgn0_q_b; wire [0:3] le_shx04_sgn0_q; wire [0:3] le_shx04_sgn0_din; wire [0:3] be_shx01_sgn0_q_b; wire [0:3] be_shx01_sgn0_q; wire [0:3] be_shx01_sgn0_din; wire [0:3] le_shx01_sgn0_q_b; wire [0:3] le_shx01_sgn0_q; wire [0:3] le_shx01_sgn0_din; wire [0:15] mxbele_b; wire [0:15] mxbele; wire [0:15] mx1_0_b; wire [0:15] mx1_1_b; wire [0:15] mx1; wire [0:15] mx2_0_b; wire [0:15] mx2_1_b; wire [0:15] mx2; wire [0:7] sx1_0_b; wire [0:7] sx1_1_b; wire [0:7] sx1; wire [0:5] sx2_0_b; wire [0:5] sx2_1_b; wire [0:5] sx2; wire [0:15] do_b; wire [0:5] sign_copy_b; wire [0:15] mxbele_d0; wire [0:15] mxbele_d1; wire [0:15] bele_s0; wire [0:15] bele_s1; wire [0:3] shx04_gp0_sel_b; wire [0:3] shx04_gp0_sel; wire [0:3] shx04_sgn0_sel_b; wire [0:3] shx04_sgn0_sel; wire [0:3] shx01_gp0_sel_b; wire [0:3] shx01_gp0_sel; wire [0:3] shx01_sgn0_sel_b; wire [0:3] shx01_sgn0_sel; wire [0:15] mx1_d0; wire [0:15] mx1_d1; wire [0:15] mx1_d2; wire [0:15] mx1_d3; wire [0:15] mx2_d0; wire [0:15] mx2_d1; wire [0:15] mx2_d2; wire [0:15] mx2_d3; wire [0:15] mx1_s0; wire [0:15] mx1_s1; wire [0:15] mx1_s2; wire [0:15] mx1_s3; wire [0:15] mx2_s0; wire [0:15] mx2_s1; wire [0:15] mx2_s2; wire [0:15] mx2_s3; wire [0:7] sx1_d0; wire [0:7] sx1_d1; wire [0:7] sx1_d2; wire [0:7] sx1_d3; wire [0:5] sx2_d0; wire [0:5] sx2_d1; wire [0:5] sx2_d2; wire [0:5] sx2_d3; wire [0:7] sx1_s0; wire [0:7] sx1_s1; wire [0:7] sx1_s2; wire [0:7] sx1_s3; wire [0:5] sx2_s0; wire [0:5] sx2_s1; wire [0:5] sx2_s2; wire [0:5] sx2_s3; wire [0:15] mask_en; wire [0:3] be_shx04_sel; wire [0:3] be_shx01_sel; wire [0:3] le_shx04_sel; wire [0:3] le_shx01_sel; wire [0:3] be_shx04_sgn; wire [0:3] be_shx01_sgn; wire [0:3] le_shx04_sgn; wire [0:3] le_shx01_sgn; wire [0:15] stq_byp_data; wire [0:15] rotate_data; //-------------------------- // constants //-------------------------- parameter bele_gp0_din_offset = 0; parameter be_shx04_gp0_din_offset = bele_gp0_din_offset + 1; parameter le_shx04_gp0_din_offset = be_shx04_gp0_din_offset + 4; parameter be_shx01_gp0_din_offset = le_shx04_gp0_din_offset + 4; parameter le_shx01_gp0_din_offset = be_shx01_gp0_din_offset + 4; parameter mask_din_offset = le_shx01_gp0_din_offset + 4; parameter be_shx04_sgn0_din_offset = mask_din_offset + 5; parameter be_shx01_sgn0_din_offset = be_shx04_sgn0_din_offset + 4; parameter le_shx04_sgn0_din_offset = be_shx01_sgn0_din_offset + 4; parameter le_shx01_sgn0_din_offset = le_shx04_sgn0_din_offset + 4; parameter scan_right = le_shx01_sgn0_din_offset + 4 - 1; wire [0:scan_right] siv; wire [0:scan_right] sov; // ############################################################################################# // Little Endian Rotate Support // Optype2 Optype4 Optype8 // B31 => rot_data(248:255) // B30 => rot_data(240:247) // B29 => rot_data(232:239) // B28 => rot_data(224:231) // B31 => rot_data(248:255) B27 => rot_data(216:223) // B30 => rot_data(240:247) B26 => rot_data(208:215) // B15 => rot_data(248:255) B29 => rot_data(232:239) B25 => rot_data(200:207) // B14 => rot_data(240:247) B28 => rot_data(224:231) B24 => rot_data(192:199) // // Optype16 // B31 => rot_data(248:255) B23 => rot_data(184:191) // B30 => rot_data(240:247) B22 => rot_data(176:183) // B29 => rot_data(232:239) B21 => rot_data(168:175) // B28 => rot_data(224:231) B20 => rot_data(160:167) // B27 => rot_data(216:223) B19 => rot_data(152:159) // B26 => rot_data(208:215) B18 => rot_data(144:151) // B25 => rot_data(200:207) B17 => rot_data(136:143) // B24 => rot_data(192:199) B16 => rot_data(128:135) // // ############################################################################################# //-- 0,1,2,3 byte rotation //with rot_sel(2 to 3) select // rot3210 <= rot_data(104 to 127) & rot_data(0 to 103) when "11", // rot_data(112 to 127) & rot_data(0 to 111) when "10", // rot_data(120 to 127) & rot_data(0 to 119) when "01", // rot_data(0 to 127) when others; // //-- 0-3,4,8,12 byte rotation //with rot_sel(0 to 1) select // rotC840 <= rot3210(32 to 127) & rot3210(0 to 31) when "11", // rot3210(64 to 127) & rot3210(0 to 63) when "10", // rot3210(96 to 127) & rot3210(0 to 95) when "01", // rot3210(0 to 127) when others; // ###################################################################### // ## BEFORE ROTATE CYCLE // ###################################################################### // Rotate Control // ---------------------------------- assign be_shx04_sel[0] = (~be_rotate_sel[0]) & (~be_rotate_sel[1]); assign be_shx04_sel[1] = (~be_rotate_sel[0]) & be_rotate_sel[1]; assign be_shx04_sel[2] = be_rotate_sel[0] & (~be_rotate_sel[1]); assign be_shx04_sel[3] = be_rotate_sel[0] & be_rotate_sel[1]; assign be_shx01_sel[0] = (~be_rotate_sel[2]) & (~be_rotate_sel[3]); assign be_shx01_sel[1] = (~be_rotate_sel[2]) & be_rotate_sel[3]; assign be_shx01_sel[2] = be_rotate_sel[2] & (~be_rotate_sel[3]); assign be_shx01_sel[3] = be_rotate_sel[2] & be_rotate_sel[3]; assign le_shx04_sel[0] = (~le_rotate_sel[0]) & (~le_rotate_sel[1]); assign le_shx04_sel[1] = (~le_rotate_sel[0]) & le_rotate_sel[1]; assign le_shx04_sel[2] = le_rotate_sel[0] & (~le_rotate_sel[1]); assign le_shx04_sel[3] = le_rotate_sel[0] & le_rotate_sel[1]; assign le_shx01_sel[0] = (~le_rotate_sel[2]) & (~le_rotate_sel[3]); assign le_shx01_sel[1] = (~le_rotate_sel[2]) & le_rotate_sel[3]; assign le_shx01_sel[2] = le_rotate_sel[2] & (~le_rotate_sel[3]); assign le_shx01_sel[3] = le_rotate_sel[2] & le_rotate_sel[3]; // Algebraic Sign Extension Control // ---------------------------------- // come up with amount to pick the sign extend bit hw(0->30), wd(0->28) 1_1110,1_1100 assign be_shx04_sgn[0] = (~be_algebraic_sel[0]) & (~be_algebraic_sel[1]); assign be_shx04_sgn[1] = (~be_algebraic_sel[0]) & be_algebraic_sel[1]; assign be_shx04_sgn[2] = be_algebraic_sel[0] & (~be_algebraic_sel[1]); assign be_shx04_sgn[3] = be_algebraic_sel[0] & be_algebraic_sel[1]; assign le_shx04_sgn[0] = (~le_algebraic_sel[0]) & (~le_algebraic_sel[1]); assign le_shx04_sgn[1] = (~le_algebraic_sel[0]) & le_algebraic_sel[1]; assign le_shx04_sgn[2] = le_algebraic_sel[0] & (~le_algebraic_sel[1]); assign le_shx04_sgn[3] = le_algebraic_sel[0] & le_algebraic_sel[1]; assign be_shx01_sgn[0] = (~be_algebraic_sel[2]) & (~be_algebraic_sel[3]) & algebraic; assign be_shx01_sgn[1] = (~be_algebraic_sel[2]) & be_algebraic_sel[3] & algebraic; assign be_shx01_sgn[2] = be_algebraic_sel[2] & (~be_algebraic_sel[3]) & algebraic; assign be_shx01_sgn[3] = be_algebraic_sel[2] & be_algebraic_sel[3] & algebraic; assign le_shx01_sgn[0] = (~le_algebraic_sel[2]) & (~le_algebraic_sel[3]) & algebraic; assign le_shx01_sgn[1] = (~le_algebraic_sel[2]) & le_algebraic_sel[3] & algebraic; assign le_shx01_sgn[2] = le_algebraic_sel[2] & (~le_algebraic_sel[3]) & algebraic; assign le_shx01_sgn[3] = le_algebraic_sel[2] & le_algebraic_sel[3] & algebraic; // Opsize Mask Generation // ---------------------------------- assign mask_din[0] = opsize[0]; // for 16:23 assign mask_din[1] = opsize[0] | opsize[1]; // for 24:27 assign mask_din[2] = opsize[0] | opsize[1] | opsize[2]; // for 28:29 assign mask_din[3] = opsize[0] | opsize[1] | opsize[2] | opsize[3]; // for 30 assign mask_din[4] = opsize[0] | opsize[1] | opsize[2] | opsize[3] | opsize[4]; // for 31 // Latch Inputs // ---------------------------------- assign bele_gp0_din[0] = le; assign be_shx04_gp0_din[0:3] = be_shx04_sel[0:3]; assign le_shx04_gp0_din[0:3] = le_shx04_sel[0:3]; assign be_shx01_gp0_din[0:3] = be_shx01_sel[0:3]; assign le_shx01_gp0_din[0:3] = le_shx01_sel[0:3]; assign be_shx04_sgn0_din[0:3] = be_shx04_sgn[0:3]; assign be_shx01_sgn0_din[0:3] = be_shx01_sgn[0:3]; assign le_shx04_sgn0_din[0:3] = le_shx04_sgn[0:3]; assign le_shx01_sgn0_din[0:3] = le_shx01_sgn[0:3]; // ###################################################################### // ## BIG-ENDIAN ROTATE CYCLE // ###################################################################### // ------------------------------------------------------------------- // local latch inputs // ------------------------------------------------------------------- tri_inv bele_gp0_q_0 (.y(bele_gp0_q), .a(bele_gp0_q_b)); tri_inv #(.WIDTH(4)) be_shx04_gp0_q_0 (.y(be_shx04_gp0_q[0:3]), .a(be_shx04_gp0_q_b[0:3])); tri_inv #(.WIDTH(4)) le_shx04_gp0_q_0 (.y(le_shx04_gp0_q[0:3]), .a(le_shx04_gp0_q_b[0:3])); tri_inv #(.WIDTH(4)) be_shx01_gp0_q_0 (.y(be_shx01_gp0_q[0:3]), .a(be_shx01_gp0_q_b[0:3])); tri_inv #(.WIDTH(4)) le_shx01_gp0_q_0 (.y(le_shx01_gp0_q[0:3]), .a(le_shx01_gp0_q_b[0:3])); tri_inv #(.WIDTH(4)) be_shx04_sgn0_q_0 (.y(be_shx04_sgn0_q[0:3]), .a(be_shx04_sgn0_q_b[0:3])); tri_inv #(.WIDTH(4)) le_shx04_sgn0_q_0 (.y(le_shx04_sgn0_q[0:3]), .a(le_shx04_sgn0_q_b[0:3])); tri_inv #(.WIDTH(4)) be_shx01_sgn0_q_0 (.y(be_shx01_sgn0_q[0:3]), .a(be_shx01_sgn0_q_b[0:3])); tri_inv #(.WIDTH(4)) le_shx01_sgn0_q_0 (.y(le_shx01_sgn0_q[0:3]), .a(le_shx01_sgn0_q_b[0:3])); assign mask_q[0:4] = (~mask_q_b[0:4]); // ---------------------------------------------------------------------------------------- // Read-Modify-Write Bypass Data Muxing // ---------------------------------------------------------------------------------------- assign stq_byp_data = ({16{stq7_byp_val}} & stq7_rmw_data) | ({16{~stq7_byp_val}} & stq8_rmw_data); assign rotate_data = ({16{stq_byp_val}} & stq_byp_data) | ({16{~stq_byp_val}} & arr_data); // ---------------------------------------------------------------------------------------- // Little/Big Endian Muxing // ---------------------------------------------------------------------------------------- assign bele_s0[0:15] = {16{~bele_gp0_q[0]}}; assign bele_s1[0:15] = {16{ bele_gp0_q[0]}}; tri_aoi22 #(.WIDTH(4)) shx04_gp0_sel_b_0 (.y(shx04_gp0_sel_b[0:3]), .a0(be_shx04_gp0_q[0:3]), .a1(bele_s0[0:3]), .b0(le_shx04_gp0_q[0:3]), .b1(bele_s1[0:3])); tri_aoi22 #(.WIDTH(4)) shx01_gp0_sel_b_0 (.y(shx01_gp0_sel_b[0:3]), .a0(be_shx01_gp0_q[0:3]), .a1(bele_s0[4:7]), .b0(le_shx01_gp0_q[0:3]), .b1(bele_s1[4:7])); tri_aoi22 #(.WIDTH(4)) shx04_sgn0_sel_b_0 (.y(shx04_sgn0_sel_b[0:3]), .a0(be_shx04_sgn0_q[0:3]), .a1(bele_s0[8:11]), .b0(le_shx04_sgn0_q[0:3]), .b1(bele_s1[8:11])); tri_aoi22 #(.WIDTH(4)) shx01_sgn0_sel_b_0 (.y(shx01_sgn0_sel_b[0:3]), .a0(be_shx01_sgn0_q[0:3]), .a1(bele_s0[12:15]), .b0(le_shx01_sgn0_q[0:3]), .b1(bele_s1[12:15])); assign shx04_gp0_sel = (~shx04_gp0_sel_b); assign shx01_gp0_sel = (~shx01_gp0_sel_b); assign shx04_sgn0_sel = (~shx04_sgn0_sel_b); assign shx01_sgn0_sel = (~shx01_sgn0_sel_b); assign mxbele_d0[0] = rotate_data[0]; assign mxbele_d1[0] = rotate_data[15]; assign mxbele_d0[1] = rotate_data[1]; assign mxbele_d1[1] = rotate_data[14]; assign mxbele_d0[2] = rotate_data[2]; assign mxbele_d1[2] = rotate_data[13]; assign mxbele_d0[3] = rotate_data[3]; assign mxbele_d1[3] = rotate_data[12]; assign mxbele_d0[4] = rotate_data[4]; assign mxbele_d1[4] = rotate_data[11]; assign mxbele_d0[5] = rotate_data[5]; assign mxbele_d1[5] = rotate_data[10]; assign mxbele_d0[6] = rotate_data[6]; assign mxbele_d1[6] = rotate_data[9]; assign mxbele_d0[7] = rotate_data[7]; assign mxbele_d1[7] = rotate_data[8]; assign mxbele_d0[8] = rotate_data[8]; assign mxbele_d1[8] = rotate_data[7]; assign mxbele_d0[9] = rotate_data[9]; assign mxbele_d1[9] = rotate_data[6]; assign mxbele_d0[10] = rotate_data[10]; assign mxbele_d1[10] = rotate_data[5]; assign mxbele_d0[11] = rotate_data[11]; assign mxbele_d1[11] = rotate_data[4]; assign mxbele_d0[12] = rotate_data[12]; assign mxbele_d1[12] = rotate_data[3]; assign mxbele_d0[13] = rotate_data[13]; assign mxbele_d1[13] = rotate_data[2]; assign mxbele_d0[14] = rotate_data[14]; assign mxbele_d1[14] = rotate_data[1]; assign mxbele_d0[15] = rotate_data[15]; assign mxbele_d1[15] = rotate_data[0]; tri_aoi22 #(.WIDTH(16)) mxbele_b_0 (.y(mxbele_b[0:15]), .a0(mxbele_d0[0:15]), .a1(bele_s0[0:15]), .b0(mxbele_d1[0:15]), .b1(bele_s1[0:15])); tri_inv #(.WIDTH(16)) mxbele_0 (.y(mxbele[0:15]), .a(mxbele_b[0:15])); // ---------------------------------------------------------------------------------------- // First level of muxing <0,4,8,12 bytes> // ---------------------------------------------------------------------------------------- assign mx1_s0[0:15] = {16{shx04_gp0_sel[0]}}; assign mx1_s1[0:15] = {16{shx04_gp0_sel[1]}}; assign mx1_s2[0:15] = {16{shx04_gp0_sel[2]}}; assign mx1_s3[0:15] = {16{shx04_gp0_sel[3]}}; assign mx1_d0[0] = mxbele[0]; assign mx1_d1[0] = mxbele[12]; assign mx1_d2[0] = mxbele[8]; assign mx1_d3[0] = mxbele[4]; assign mx1_d0[1] = mxbele[1]; assign mx1_d1[1] = mxbele[13]; assign mx1_d2[1] = mxbele[9]; assign mx1_d3[1] = mxbele[5]; assign mx1_d0[2] = mxbele[2]; assign mx1_d1[2] = mxbele[14]; assign mx1_d2[2] = mxbele[10]; assign mx1_d3[2] = mxbele[6]; assign mx1_d0[3] = mxbele[3]; assign mx1_d1[3] = mxbele[15]; assign mx1_d2[3] = mxbele[11]; assign mx1_d3[3] = mxbele[7]; assign mx1_d0[4] = mxbele[4]; assign mx1_d1[4] = mxbele[0]; assign mx1_d2[4] = mxbele[12]; assign mx1_d3[4] = mxbele[8]; assign mx1_d0[5] = mxbele[5]; assign mx1_d1[5] = mxbele[1]; assign mx1_d2[5] = mxbele[13]; assign mx1_d3[5] = mxbele[9]; assign mx1_d0[6] = mxbele[6]; assign mx1_d1[6] = mxbele[2]; assign mx1_d2[6] = mxbele[14]; assign mx1_d3[6] = mxbele[10]; assign mx1_d0[7] = mxbele[7]; assign mx1_d1[7] = mxbele[3]; assign mx1_d2[7] = mxbele[15]; assign mx1_d3[7] = mxbele[11]; assign mx1_d0[8] = mxbele[8]; assign mx1_d1[8] = mxbele[4]; assign mx1_d2[8] = mxbele[0]; assign mx1_d3[8] = mxbele[12]; assign mx1_d0[9] = mxbele[9]; assign mx1_d1[9] = mxbele[5]; assign mx1_d2[9] = mxbele[1]; assign mx1_d3[9] = mxbele[13]; assign mx1_d0[10] = mxbele[10]; assign mx1_d1[10] = mxbele[6]; assign mx1_d2[10] = mxbele[2]; assign mx1_d3[10] = mxbele[14]; assign mx1_d0[11] = mxbele[11]; assign mx1_d1[11] = mxbele[7]; assign mx1_d2[11] = mxbele[3]; assign mx1_d3[11] = mxbele[15]; assign mx1_d0[12] = mxbele[12]; assign mx1_d1[12] = mxbele[8]; assign mx1_d2[12] = mxbele[4]; assign mx1_d3[12] = mxbele[0]; assign mx1_d0[13] = mxbele[13]; assign mx1_d1[13] = mxbele[9]; assign mx1_d2[13] = mxbele[5]; assign mx1_d3[13] = mxbele[1]; assign mx1_d0[14] = mxbele[14]; assign mx1_d1[14] = mxbele[10]; assign mx1_d2[14] = mxbele[6]; assign mx1_d3[14] = mxbele[2]; assign mx1_d0[15] = mxbele[15]; assign mx1_d1[15] = mxbele[11]; assign mx1_d2[15] = mxbele[7]; assign mx1_d3[15] = mxbele[3]; tri_aoi22 #(.WIDTH(16)) mx1_0_b_0 (.y(mx1_0_b[0:15]), .a0(mx1_s0[0:15]), .a1(mx1_d0[0:15]), .b0(mx1_s1[0:15]), .b1(mx1_d1[0:15])); tri_aoi22 #(.WIDTH(16)) mx1_1_b_0 (.y(mx1_1_b[0:15]), .a0(mx1_s2[0:15]), .a1(mx1_d2[0:15]), .b0(mx1_s3[0:15]), .b1(mx1_d3[0:15])); tri_nand2 #(.WIDTH(16)) mx1_0 (.y(mx1[0:15]), .a(mx1_0_b[0:15]), .b(mx1_1_b[0:15])); assign sx1_s0[0:7] = {8{shx04_sgn0_sel[0]}}; assign sx1_s1[0:7] = {8{shx04_sgn0_sel[1]}}; assign sx1_s2[0:7] = {8{shx04_sgn0_sel[2]}}; assign sx1_s3[0:7] = {8{shx04_sgn0_sel[3]}}; assign sx1_d0[0] = rotate_data[0]; assign sx1_d1[0] = rotate_data[4]; assign sx1_d2[0] = rotate_data[8]; assign sx1_d3[0] = rotate_data[12]; assign sx1_d0[1] = rotate_data[1]; assign sx1_d1[1] = rotate_data[5]; assign sx1_d2[1] = rotate_data[9]; assign sx1_d3[1] = rotate_data[13]; assign sx1_d0[2] = rotate_data[2]; assign sx1_d1[2] = rotate_data[6]; assign sx1_d2[2] = rotate_data[10]; assign sx1_d3[2] = rotate_data[14]; assign sx1_d0[3] = rotate_data[3]; assign sx1_d1[3] = rotate_data[7]; assign sx1_d2[3] = rotate_data[11]; assign sx1_d3[3] = rotate_data[15]; assign sx1_d0[4] = rotate_data[0]; assign sx1_d1[4] = rotate_data[4]; assign sx1_d2[4] = rotate_data[8]; assign sx1_d3[4] = rotate_data[12]; assign sx1_d0[5] = rotate_data[1]; assign sx1_d1[5] = rotate_data[5]; assign sx1_d2[5] = rotate_data[9]; assign sx1_d3[5] = rotate_data[13]; assign sx1_d0[6] = rotate_data[2]; assign sx1_d1[6] = rotate_data[6]; assign sx1_d2[6] = rotate_data[10]; assign sx1_d3[6] = rotate_data[14]; assign sx1_d0[7] = rotate_data[3]; assign sx1_d1[7] = rotate_data[7]; assign sx1_d2[7] = rotate_data[11]; assign sx1_d3[7] = rotate_data[15]; tri_aoi22 #(.WIDTH(8)) sx1_0_b_0 (.y(sx1_0_b[0:7]), .a0(sx1_s0[0:7]), .a1(sx1_d0[0:7]), .b0(sx1_s1[0:7]), .b1(sx1_d1[0:7])); tri_aoi22 #(.WIDTH(8)) sx1_1_b_0 (.y(sx1_1_b[0:7]), .a0(sx1_s2[0:7]), .a1(sx1_d2[0:7]), .b0(sx1_s3[0:7]), .b1(sx1_d3[0:7])); tri_nand2 #(.WIDTH(8)) sx1_0 (.y(sx1[0:7]), .a(sx1_0_b[0:7]), .b(sx1_1_b[0:7])); // ---------------------------------------------------------------------------------------- // third level of muxing <0,1,2,3 bytes> , include mask on selects // ---------------------------------------------------------------------------------------- assign mask_en[0:7] = {8{mask_q[0]}}; // 128 assign mask_en[8:11] = {4{mask_q[1]}}; // 128,64 assign mask_en[12:13] = {2{mask_q[2]}}; // 128,64,32 assign mask_en[14] = mask_q[3]; // 128,64,32,16 assign mask_en[15] = mask_q[4]; // 128,64,32,16,8 <not sure you really need this one> assign mx2_s0[0:7] = {8{shx01_gp0_sel[0]}} & mask_en[0:7]; assign mx2_s1[0:7] = {8{shx01_gp0_sel[1]}} & mask_en[0:7]; assign mx2_s2[0:7] = {8{shx01_gp0_sel[2]}} & mask_en[0:7]; assign mx2_s3[0:7] = {8{shx01_gp0_sel[3]}} & mask_en[0:7]; assign mx2_s0[8:15] = {8{shx01_gp0_sel[0]}} & mask_en[8:15]; assign mx2_s1[8:15] = {8{shx01_gp0_sel[1]}} & mask_en[8:15]; assign mx2_s2[8:15] = {8{shx01_gp0_sel[2]}} & mask_en[8:15]; assign mx2_s3[8:15] = {8{shx01_gp0_sel[3]}} & mask_en[8:15]; assign mx2_d0[0] = mx1[0]; assign mx2_d1[0] = mx1[15]; assign mx2_d2[0] = mx1[14]; assign mx2_d3[0] = mx1[13]; assign mx2_d0[1] = mx1[1]; assign mx2_d1[1] = mx1[0]; assign mx2_d2[1] = mx1[15]; assign mx2_d3[1] = mx1[14]; assign mx2_d0[2] = mx1[2]; assign mx2_d1[2] = mx1[1]; assign mx2_d2[2] = mx1[0]; assign mx2_d3[2] = mx1[15]; assign mx2_d0[3] = mx1[3]; assign mx2_d1[3] = mx1[2]; assign mx2_d2[3] = mx1[1]; assign mx2_d3[3] = mx1[0]; assign mx2_d0[4] = mx1[4]; assign mx2_d1[4] = mx1[3]; assign mx2_d2[4] = mx1[2]; assign mx2_d3[4] = mx1[1]; assign mx2_d0[5] = mx1[5]; assign mx2_d1[5] = mx1[4]; assign mx2_d2[5] = mx1[3]; assign mx2_d3[5] = mx1[2]; assign mx2_d0[6] = mx1[6]; assign mx2_d1[6] = mx1[5]; assign mx2_d2[6] = mx1[4]; assign mx2_d3[6] = mx1[3]; assign mx2_d0[7] = mx1[7]; assign mx2_d1[7] = mx1[6]; assign mx2_d2[7] = mx1[5]; assign mx2_d3[7] = mx1[4]; assign mx2_d0[8] = mx1[8]; assign mx2_d1[8] = mx1[7]; assign mx2_d2[8] = mx1[6]; assign mx2_d3[8] = mx1[5]; assign mx2_d0[9] = mx1[9]; assign mx2_d1[9] = mx1[8]; assign mx2_d2[9] = mx1[7]; assign mx2_d3[9] = mx1[6]; assign mx2_d0[10] = mx1[10]; assign mx2_d1[10] = mx1[9]; assign mx2_d2[10] = mx1[8]; assign mx2_d3[10] = mx1[7]; assign mx2_d0[11] = mx1[11]; assign mx2_d1[11] = mx1[10]; assign mx2_d2[11] = mx1[9]; assign mx2_d3[11] = mx1[8]; assign mx2_d0[12] = mx1[12]; assign mx2_d1[12] = mx1[11]; assign mx2_d2[12] = mx1[10]; assign mx2_d3[12] = mx1[9]; assign mx2_d0[13] = mx1[13]; assign mx2_d1[13] = mx1[12]; assign mx2_d2[13] = mx1[11]; assign mx2_d3[13] = mx1[10]; assign mx2_d0[14] = mx1[14]; assign mx2_d1[14] = mx1[13]; assign mx2_d2[14] = mx1[12]; assign mx2_d3[14] = mx1[11]; assign mx2_d0[15] = mx1[15]; assign mx2_d1[15] = mx1[14]; assign mx2_d2[15] = mx1[13]; assign mx2_d3[15] = mx1[12]; tri_aoi22 #(.WIDTH(16)) mx2_0_b_0 (.y(mx2_0_b[0:15]), .a0(mx2_s0[0:15]), .a1(mx2_d0[0:15]), .b0(mx2_s1[0:15]), .b1(mx2_d1[0:15])); tri_aoi22 #(.WIDTH(16)) mx2_1_b_0 (.y(mx2_1_b[0:15]), .a0(mx2_s2[0:15]), .a1(mx2_d2[0:15]), .b0(mx2_s3[0:15]), .b1(mx2_d3[0:15])); tri_nand2 #(.WIDTH(16)) mx2_0 (.y(mx2[0:15]), .a(mx2_0_b[0:15]), .b(mx2_1_b[0:15])); tri_inv #(.WIDTH(16)) do_b_0 (.y(do_b[0:15]), .a(mx2[0:15])); tri_inv #(.WIDTH(16)) data_rot_0 (.y(data_rot[0:15]), .a(do_b[0:15])); tri_inv #(.WIDTH(16)) data_latched_b_0 (.y(data_latched_b), .a(arr_data)); tri_inv #(.WIDTH(16)) data_latched_0 (.y(data_latched), .a(data_latched_b)); assign sx2_s0[0:3] = {4{shx01_sgn0_sel[0]}}; assign sx2_s1[0:3] = {4{shx01_sgn0_sel[1]}}; assign sx2_s2[0:3] = {4{shx01_sgn0_sel[2]}}; assign sx2_s3[0:3] = {4{shx01_sgn0_sel[3]}}; assign sx2_s0[4:5] = {2{shx01_sgn0_sel[0] & (~mask_q[2])}}; assign sx2_s1[4:5] = {2{shx01_sgn0_sel[1] & (~mask_q[2])}}; assign sx2_s2[4:5] = {2{shx01_sgn0_sel[2] & (~mask_q[2])}}; assign sx2_s3[4:5] = {2{shx01_sgn0_sel[3] & (~mask_q[2])}}; // 6 logically identical copies (1 per byte needing extension) assign sx2_d0[0] = sx1[0]; assign sx2_d1[0] = sx1[1]; assign sx2_d2[0] = sx1[2]; assign sx2_d3[0] = sx1[3]; assign sx2_d0[1] = sx1[0]; assign sx2_d1[1] = sx1[1]; assign sx2_d2[1] = sx1[2]; assign sx2_d3[1] = sx1[3]; assign sx2_d0[2] = sx1[0]; assign sx2_d1[2] = sx1[1]; assign sx2_d2[2] = sx1[2]; assign sx2_d3[2] = sx1[3]; assign sx2_d0[3] = sx1[4]; assign sx2_d1[3] = sx1[5]; assign sx2_d2[3] = sx1[6]; assign sx2_d3[3] = sx1[7]; assign sx2_d0[4] = sx1[4]; assign sx2_d1[4] = sx1[5]; assign sx2_d2[4] = sx1[6]; assign sx2_d3[4] = sx1[7]; assign sx2_d0[5] = sx1[4]; assign sx2_d1[5] = sx1[5]; assign sx2_d2[5] = sx1[6]; assign sx2_d3[5] = sx1[7]; tri_aoi22 #(.WIDTH(6)) sx2_0_b_0 (.y(sx2_0_b[0:5]), .a0(sx2_s0[0:5]), .a1(sx2_d0[0:5]), .b0(sx2_s1[0:5]), .b1(sx2_d1[0:5])); tri_aoi22 #(.WIDTH(6)) sx2_1_b_0 (.y(sx2_1_b[0:5]), .a0(sx2_s2[0:5]), .a1(sx2_d2[0:5]), .b0(sx2_s3[0:5]), .b1(sx2_d3[0:5])); tri_nand2 #(.WIDTH(6)) sx2_0 (.y(sx2[0:5]), .a(sx2_0_b[0:5]), .b(sx2_1_b[0:5])); tri_inv #(.WIDTH(6)) sign_copy_b_0 (.y(sign_copy_b[0:5]), .a(sx2[0:5])); tri_inv #(.WIDTH(6)) algebraic_bit_0 (.y(algebraic_bit[0:5]), .a(sign_copy_b[0:5])); // top funny physical placement to minimize wrap wires ... also nice for LE adjust //--------- // 0 31 // 1 30 // 2 29 // 3 28 // 4 27 // 5 26 // 6 25 // 7 24 //--------- // 8 23 // 9 22 // 10 21 // 11 20 // 12 19 // 13 18 // 14 17 // 15 16 //--------- // bot // ############################################################### // ## LCBs // ############################################################### tri_lcbnd my_lcb( .delay_lclkr(delay_lclkr_dc), .mpw1_b(mpw1_dc_b), .mpw2_b(mpw2_dc_b), .force_t(func_sl_force), .nclk(nclk), .vd(vdd), .gd(gnd), .act(act), .sg(sg_0), .thold_b(func_sl_thold_0_b), .d1clk(my_d1clk), .d2clk(my_d2clk), .lclk(my_lclk) ); // ############################################################### // ## Latches // ############################################################### tri_inv_nlats #(.WIDTH(1), .INIT(1'b0), .BTR("NLI0001_X2_A12TH"), .NEEDS_SRESET(0)) bele_gp0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[bele_gp0_din_offset:bele_gp0_din_offset + 1 - 1]), .scanout(sov[bele_gp0_din_offset:bele_gp0_din_offset + 1 - 1]), .d(bele_gp0_din), .qb(bele_gp0_q_b) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X2_A12TH"), .NEEDS_SRESET(0)) be_shx04_gp0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[be_shx04_gp0_din_offset:be_shx04_gp0_din_offset + 4 - 1]), .scanout(sov[be_shx04_gp0_din_offset:be_shx04_gp0_din_offset + 4 - 1]), .d(be_shx04_gp0_din), .qb(be_shx04_gp0_q_b[0:3]) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X2_A12TH"), .NEEDS_SRESET(0)) le_shx04_gp0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[le_shx04_gp0_din_offset:le_shx04_gp0_din_offset + 4 - 1]), .scanout(sov[le_shx04_gp0_din_offset:le_shx04_gp0_din_offset + 4 - 1]), .d(le_shx04_gp0_din), .qb(le_shx04_gp0_q_b[0:3]) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X1_A12TH"), .NEEDS_SRESET(0)) be_shx01_gp0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[be_shx01_gp0_din_offset:be_shx01_gp0_din_offset + 4 - 1]), .scanout(sov[be_shx01_gp0_din_offset:be_shx01_gp0_din_offset + 4 - 1]), .d(be_shx01_gp0_din), .qb(be_shx01_gp0_q_b[0:3]) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X1_A12TH"), .NEEDS_SRESET(0)) le_shx01_gp0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[le_shx01_gp0_din_offset:le_shx01_gp0_din_offset + 4 - 1]), .scanout(sov[le_shx01_gp0_din_offset:le_shx01_gp0_din_offset + 4 - 1]), .d(le_shx01_gp0_din), .qb(le_shx01_gp0_q_b[0:3]) ); tri_inv_nlats #(.WIDTH(5), .INIT(5'b0), .BTR("NLI0001_X1_A12TH"), .NEEDS_SRESET(0)) mask_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[mask_din_offset:mask_din_offset + 5 - 1]), .scanout(sov[mask_din_offset:mask_din_offset + 5 - 1]), .d(mask_din), .qb(mask_q_b[0:4]) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X2_A12TH"), .NEEDS_SRESET(0)) be_shx04_sgn0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[be_shx04_sgn0_din_offset:be_shx04_sgn0_din_offset + 4 - 1]), .scanout(sov[be_shx04_sgn0_din_offset:be_shx04_sgn0_din_offset + 4 - 1]), .d(be_shx04_sgn0_din), .qb(be_shx04_sgn0_q_b) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X1_A12TH"), .NEEDS_SRESET(0)) be_shx01_sgn0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[be_shx01_sgn0_din_offset:be_shx01_sgn0_din_offset + 4 - 1]), .scanout(sov[be_shx01_sgn0_din_offset:be_shx01_sgn0_din_offset + 4 - 1]), .d(be_shx01_sgn0_din), .qb(be_shx01_sgn0_q_b) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X2_A12TH"), .NEEDS_SRESET(0)) le_shx04_sgn0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[le_shx04_sgn0_din_offset:le_shx04_sgn0_din_offset + 4 - 1]), .scanout(sov[le_shx04_sgn0_din_offset:le_shx04_sgn0_din_offset + 4 - 1]), .d(le_shx04_sgn0_din), .qb(le_shx04_sgn0_q_b) ); tri_inv_nlats #(.WIDTH(4), .INIT(4'h0), .BTR("NLI0001_X1_A12TH"), .NEEDS_SRESET(0)) le_shx01_sgn0_lat( .vd(vdd), .gd(gnd), .lclk(my_lclk), .d1clk(my_d1clk), .d2clk(my_d2clk), .scanin(siv[le_shx01_sgn0_din_offset:le_shx01_sgn0_din_offset + 4 - 1]), .scanout(sov[le_shx01_sgn0_din_offset:le_shx01_sgn0_din_offset + 4 - 1]), .d(le_shx01_sgn0_din), .qb(le_shx01_sgn0_q_b) ); assign siv[0:scan_right] = {sov[1:scan_right], scan_in}; assign scan_out = sov[0]; endmodule