| //**************************************************************************** |
| // |
| // Copyright 2017-2023 Vivante Corporation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // 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. |
| // |
| //**************************************************************************** |
| // Auto-generated file on 11/03/2023. |
| // |
| //**************************************************************************** |
| |
| module upsize_rd_chan |
| ( |
| archannel_ready, rready_m, rvalid_s, rdata_s, rid_s, rresp_s, |
| rlast_s, ruser_s, |
| aclk, aresetn, archannel_valid, archannel_data, rvalid_m, rdata_m, |
| rid_m, rresp_m, rlast_m, ruser_m, rready_s |
| ); |
| parameter ARID_WIDTH=4; |
| parameter AWID_WIDTH=4; |
| parameter ADDR_WIDTH=32; |
| parameter US_DATA_WIDTH=128; |
| parameter DS_DATA_WIDTH=256; |
| parameter USER_WIDTH=4; |
| parameter RD_ISS=8; |
| localparam DS_WSTRB_WIDTH=DS_DATA_WIDTH/8; |
| localparam US_WSTRB_WIDTH=US_DATA_WIDTH/8; |
| localparam DS_ADDR_AL_WIDTH=$clog2(DS_WSTRB_WIDTH); |
| localparam US_ADDR_AL_WIDTH=$clog2(US_WSTRB_WIDTH); |
| localparam ARFMT_WIDTH=1+1+ARID_WIDTH+DS_ADDR_AL_WIDTH*3+1+3; |
| localparam AWFMT_WIDTH=1+US_ADDR_AL_WIDTH*2+3+1; |
| localparam US_AW_WIDTH=4+USER_WIDTH+AWID_WIDTH+ADDR_WIDTH+8+3+2+2+4+4+3+1; |
| localparam US_AR_WIDTH=4+USER_WIDTH+ARID_WIDTH+ADDR_WIDTH+8+3+2+2+4+4+3+1; |
| localparam US_R_WIDTH=USER_WIDTH+ARID_WIDTH+US_DATA_WIDTH+2+1; |
| localparam US_W_WIDTH=USER_WIDTH+AWID_WIDTH+US_DATA_WIDTH+US_WSTRB_WIDTH+1; |
| localparam US_B_WIDTH=USER_WIDTH+AWID_WIDTH+2; |
| localparam PTR_WIDTH=$clog2(RD_ISS+1); |
| localparam UPSIZE_WIDTH=DS_ADDR_AL_WIDTH-US_ADDR_AL_WIDTH; |
| localparam DATA_RATIO=(DS_DATA_WIDTH/US_DATA_WIDTH); |
| input aclk; |
| input aresetn; |
| input archannel_valid; |
| output archannel_ready; |
| input [ARFMT_WIDTH-1:0] archannel_data; |
| input rvalid_m; |
| output rready_m; |
| input [DS_DATA_WIDTH-1:0] rdata_m; |
| input [ARID_WIDTH-1:0] rid_m; |
| input [1:0] rresp_m; |
| input rlast_m; |
| input [USER_WIDTH-1:0] ruser_m; |
| input rready_s; |
| output rvalid_s; |
| output [US_DATA_WIDTH-1:0] rdata_s; |
| output [ARID_WIDTH-1:0] rid_s; |
| output [1:0] rresp_s; |
| output rlast_s; |
| output [USER_WIDTH-1:0] ruser_s; |
| wire archannel_ready_i; |
| wire [RD_ISS-1:0] match_bus; |
| wire [RD_ISS-1:0] hazard_bus; |
| wire [RD_ISS-1:0] valid_bus; |
| wire [RD_ISS-1:0] last_addr_match_bus; |
| wire [RD_ISS-1:0] beat_complete_slice_bus; |
| wire hazard; |
| wire last_addr_match; |
| wire beat_complete_slice; |
| wire archannel_hndshk; |
| wire rchannel_hndshk; |
| wire push_slice; |
| wire pop_slice; |
| wire update; |
| wire beat_complete; |
| wire [UPSIZE_WIDTH-1:0] data_select; |
| reg [UPSIZE_WIDTH-1:0] addr; |
| wire [ARID_WIDTH-1:0] rid_m; |
| wire [DS_DATA_WIDTH-1:0] rdata; |
| wire rlast_in; |
| wire rlast_s_i; |
| wire [1:0] rresp_s; |
| wire [UPSIZE_WIDTH-1:0] addr_out[RD_ISS-1:0]; |
| wire [US_WSTRB_WIDTH-1:0] rdata_byte_mask[RD_ISS-1:0]; |
| wire [RD_ISS-1:0] const_onehot[RD_ISS-1:0]; |
| wire [RD_ISS-1:0] valid_bus_zero_lsb; |
| wire [PTR_WIDTH-1:0] hazard_bus_one_pos[RD_ISS-1:0]; |
| wire [PTR_WIDTH-1:0] match_bus_one_pos[RD_ISS-1:0]; |
| reg [US_DATA_WIDTH-1:0] rdata_beat_mask; |
| reg [US_DATA_WIDTH-1:0] rdata_s_demux; |
| reg [PTR_WIDTH-1:0] hazard_pointer; |
| reg [PTR_WIDTH-1:0] match_pointer; |
| reg [RD_ISS-1:0] store; |
| assign rid_s = rid_m; |
| assign rlast_in = rlast_m; |
| assign rresp_s = rresp_m; |
| assign ruser_s = ruser_m; |
| assign rdata = rdata_m; |
| assign hazard = |hazard_bus; |
| assign last_addr_match = |(last_addr_match_bus & match_bus); |
| assign beat_complete_slice = |(beat_complete_slice_bus & match_bus); |
| always @(*) |
| begin:for_addr |
| integer i,j; |
| addr = {UPSIZE_WIDTH{1'h0}}; |
| for(i=0;i<UPSIZE_WIDTH;i=i+1) |
| begin: for_addr_i |
| for(j=0;j<RD_ISS;j=j+1) |
| begin: for_addr_j |
| addr[i] = addr[i]|addr_out[j][i]; |
| end |
| end |
| end |
| reg [US_WSTRB_WIDTH-1:0] rdata_byte_mask_i; |
| always @(*) |
| begin:for_rdata_beat |
| integer i,j; |
| rdata_beat_mask = {US_DATA_WIDTH{1'b0}}; |
| for(i=0;i<US_WSTRB_WIDTH;i=i+1) |
| for(j=0;j<8;j=j+1) |
| rdata_beat_mask[i*8+j] = rdata_byte_mask_i[i]; |
| end |
| always @(*) |
| begin:for_rdata_byte |
| integer i,j; |
| rdata_byte_mask_i = {US_WSTRB_WIDTH{1'b0}}; |
| for(i=0;i<US_WSTRB_WIDTH;i=i+1) |
| for(j=0;j<RD_ISS;j=j+1) |
| begin |
| rdata_byte_mask_i[i] = rdata_byte_mask_i[i] | rdata_byte_mask[j][i] ; |
| end |
| end |
| assign data_select = addr; |
| /* |
| always@(*) |
| begin:rdata_s_demux_a |
| integer i; |
| for(i=0;i<DATA_RATIO;i=i+1) |
| begin |
| if(data_select == i) |
| begin |
| rdata_s_demux = rdata[US_DATA_WIDTH*i+:US_DATA_WIDTH];//[(US_DATA_WIDTH*(i+1)-1):US_DATA_WIDTH*i]; |
| end |
| end |
| end |
| */ |
| generate |
| if(DATA_RATIO==2) |
| begin:demux_D2 |
| always@(*) |
| begin |
| case(data_select) |
| 0:rdata_s_demux=rdata[US_DATA_WIDTH-1:0]; |
| 1:rdata_s_demux=rdata[US_DATA_WIDTH*2-1:US_DATA_WIDTH]; |
| default:rdata_s_demux= {US_DATA_WIDTH{1'b0}}; |
| endcase |
| end |
| end |
| else if(DATA_RATIO==4) |
| begin:demux_D4 |
| always@(*) |
| begin |
| case(data_select) |
| 0:rdata_s_demux=rdata[US_DATA_WIDTH-1:0]; |
| 1:rdata_s_demux=rdata[US_DATA_WIDTH*2-1:US_DATA_WIDTH]; |
| 2:rdata_s_demux=rdata[US_DATA_WIDTH*3-1:US_DATA_WIDTH*2]; |
| 3:rdata_s_demux=rdata[US_DATA_WIDTH*4-1:US_DATA_WIDTH*3]; |
| default:rdata_s_demux={US_DATA_WIDTH{1'b0}}; |
| endcase |
| end |
| end |
| else if(DATA_RATIO==8) |
| begin:demux_D8 |
| always@(*) |
| begin |
| case(data_select) |
| 0:rdata_s_demux=rdata[US_DATA_WIDTH-1:0]; |
| 1:rdata_s_demux=rdata[US_DATA_WIDTH*2-1:US_DATA_WIDTH]; |
| 2:rdata_s_demux=rdata[US_DATA_WIDTH*3-1:US_DATA_WIDTH*2]; |
| 3:rdata_s_demux=rdata[US_DATA_WIDTH*4-1:US_DATA_WIDTH*3]; |
| 4:rdata_s_demux=rdata[US_DATA_WIDTH*5-1:US_DATA_WIDTH*4]; |
| 5:rdata_s_demux=rdata[US_DATA_WIDTH*6-1:US_DATA_WIDTH*5]; |
| 6:rdata_s_demux=rdata[US_DATA_WIDTH*7-1:US_DATA_WIDTH*6]; |
| 7:rdata_s_demux=rdata[US_DATA_WIDTH*8-1:US_DATA_WIDTH*7]; |
| default:rdata_s_demux={US_DATA_WIDTH{1'b0}}; |
| endcase |
| end |
| end |
| endgenerate |
| assign rdata_s = rdata_s_demux & rdata_beat_mask; |
| assign rlast_s_i = last_addr_match && rlast_in; |
| assign rlast_s = rlast_s_i; |
| assign archannel_ready_i = ~&valid_bus; |
| assign archannel_ready = archannel_ready_i; |
| assign archannel_hndshk = archannel_ready_i && archannel_valid; |
| assign push_slice = archannel_hndshk; |
| genvar i; |
| generate |
| for(i=0;i<RD_ISS;i=i+1) begin:const_onehot_g |
| if(RD_ISS==1) begin: rd_iss_1 |
| assign const_onehot[i]=(1'h1<<i); |
| end |
| else begin: rd_iss_n |
| assign const_onehot[i]=({{(RD_ISS-1){1'h0}},1'h1}<<i); |
| end |
| assign valid_bus_zero_lsb[i]=((~valid_bus[i:0])==const_onehot[i][i:0]); |
| assign hazard_bus_one_pos[i]={PTR_WIDTH{hazard_bus[i]}}&i; |
| assign match_bus_one_pos[i]={PTR_WIDTH{match_bus[i]}}&i; |
| always @(*) |
| begin : store_decode |
| if (&valid_bus) |
| store[i] = match_bus[i]; |
| else |
| store[i] = valid_bus_zero_lsb[i]; |
| end |
| end |
| endgenerate |
| always @(*) |
| begin : hazard_num_distibution |
| integer a; |
| hazard_pointer={PTR_WIDTH{1'h0}}; |
| for(a=0;a<RD_ISS;a=a+1) begin |
| hazard_pointer=hazard_pointer | hazard_bus_one_pos[a]; |
| end |
| end |
| always @(*) |
| begin : match_num_distibution |
| integer a; |
| match_pointer={PTR_WIDTH{1'h0}}; |
| for(a=0;a<RD_ISS;a=a+1) begin |
| match_pointer=match_pointer | match_bus_one_pos[a]; |
| end |
| end |
| assign beat_complete = (rlast_s_i | beat_complete_slice) && update; |
| assign rready_m = beat_complete && rvalid_m; |
| assign rvalid_s = rvalid_m; |
| assign rchannel_hndshk = rvalid_s && rready_s; |
| assign update = rchannel_hndshk; |
| assign pop_slice = update && rlast_s_i; |
| generate |
| for(i=0;i<RD_ISS;i=i+1) begin: rd_cam_slice_inst |
| upsize_rd_cam_slice #( |
| .ARID_WIDTH(ARID_WIDTH), |
| .US_DATA_WIDTH(US_DATA_WIDTH), |
| .DS_DATA_WIDTH(DS_DATA_WIDTH), |
| .RD_ISS(RD_ISS), |
| .ARCHAN_WIDTH(ARFMT_WIDTH) |
| ) u_upsize_rd_cam_slice |
| ( |
| .aresetn (aresetn), |
| .aclk (aclk), |
| .match_id (rid_m), |
| .store (store[i]), |
| .push_slice (push_slice), |
| .pop_slice (pop_slice), |
| .update (update), |
| .match_pointer (match_pointer), |
| .archannel_data (archannel_data), |
| .rlast_in (rlast_in), |
| .hazard_in (hazard), |
| .hazard_pointer (hazard_pointer), |
| .hazard (hazard_bus[i]), |
| .match (match_bus[i]), |
| .valid (valid_bus[i]), |
| .addr_out (addr_out[i]), |
| .last_addr_match (last_addr_match_bus[i]), |
| .beat_complete (beat_complete_slice_bus[i]), |
| .rdata_byte_mask (rdata_byte_mask[i]) |
| ); |
| end |
| endgenerate |
| endmodule |