// ================================================================ // NVDLA Open Source Project // // Copyright(c) 2016 - 2017 NVIDIA Corporation. Licensed under the // NVDLA Open Hardware License; Check "LICENSE" which comes with // this distribution for more information. // ================================================================ // File Name: NV_NVDLA_CACC_delivery_buffer.v // ================================================================ // NVDLA Open Source Project // // Copyright(c) 2016 - 2017 NVIDIA Corporation. Licensed under the // NVDLA Open Hardware License; Check "LICENSE" which comes with // this distribution for more information. // ================================================================ // File Name: NV_NVDLA_CACC.h module NV_NVDLA_CACC_delivery_buffer ( nvdla_core_clk //|< i ,nvdla_core_rstn //|< i ,cacc2sdp_ready //|< i ,dbuf_rd_addr //|< i ,dbuf_rd_en //|< i ,dbuf_rd_layer_end //|< i ,dbuf_wr_addr //|< i ,dbuf_wr_data //|< i ,dbuf_wr_en //|< i ,pwrbus_ram_pd //|< i ,cacc2glb_done_intr_pd //|> o ,cacc2sdp_pd //|> o ,cacc2sdp_valid //|> o ,dbuf_rd_ready //|> o ,accu2sc_credit_size //|> o ,accu2sc_credit_vld //|> o ); input nvdla_core_clk; input nvdla_core_rstn; input cacc2sdp_ready; input [3 +1 -1:0] dbuf_rd_addr; input dbuf_rd_en; input dbuf_rd_layer_end; input [3 +1 -1:0] dbuf_wr_addr; input [32*8 -1:0] dbuf_wr_data; input dbuf_wr_en; input [31:0] pwrbus_ram_pd; output [1:0] cacc2glb_done_intr_pd; output [32*1 +2 -1:0] cacc2sdp_pd; output cacc2sdp_valid; output dbuf_rd_ready; output [2:0] accu2sc_credit_size; output accu2sc_credit_vld; // Instance RAMs wire [32*8 -1:0] dbuf_rd_data; reg [(32*8)/(32*1)-1:0] data_left_mask; wire dbuf_rd_en_new = ~(|data_left_mask) & dbuf_rd_en; // spyglass disable_block NoWidthInBasedNum-ML //: my $dep= 8*2; //: my $wid= 32*8; //: print qq( //: nv_ram_rws_${dep}x${wid} u_accu_dbuf ( //: .clk (nvdla_core_clk) //|< i //: ,.ra (dbuf_rd_addr) //|< r //: ,.re (dbuf_rd_en_new) //|< r //: ,.dout (dbuf_rd_data) //|> w //: ,.wa (dbuf_wr_addr) //|< r //: ,.we (dbuf_wr_en) //|< r //: ,.di (dbuf_wr_data) //|< r //: ,.pwrbus_ram_pd (pwrbus_ram_pd[31:0]) //|< i //: ); //: ); //| eperl: generated_beg (DO NOT EDIT BELOW) nv_ram_rws_16x256 u_accu_dbuf ( .clk (nvdla_core_clk) //|< i ,.ra (dbuf_rd_addr) //|< r ,.re (dbuf_rd_en_new) //|< r ,.dout (dbuf_rd_data) //|> w ,.wa (dbuf_wr_addr) //|< r ,.we (dbuf_wr_en) //|< r ,.di (dbuf_wr_data) //|< r ,.pwrbus_ram_pd (pwrbus_ram_pd[31:0]) //|< i ); //| eperl: generated_end (DO NOT EDIT ABOVE) //get signal for SDP //: &eperl::flop("-q dbuf_rd_valid -d \"dbuf_rd_en_new\" -clk nvdla_core_clk -rst nvdla_core_rstn "); //: my $kk=(32*8)/(32*1); //: print qq( //: reg [${kk}-1:0] rd_data_mask; //which data to be fetched by sdp. //: wire [${kk}-1:0] rd_data_mask_pre; ); //: if(${kk}>=2){ //: print "assign rd_data_mask_pre = cacc2sdp_valid & cacc2sdp_ready ? {rd_data_mask[${kk}-2:0],rd_data_mask[${kk}-1]} : rd_data_mask; \n"; //: } else { //: print "assign rd_data_mask_pre = rd_data_mask; \n"; //:} //: &eperl::flop("-nodeclare -q rd_data_mask -d rd_data_mask_pre -rval \" 'b1\" "); //: print qq( //: wire [${kk}-1:0] data_left_mask_pre = dbuf_rd_en_new ? {${kk}{1'b1}} : (cacc2sdp_valid & cacc2sdp_ready) ? (data_left_mask<<1'b1) : data_left_mask; //: ); //: &eperl::flop("-nodeclare -q data_left_mask -d data_left_mask_pre "); //| eperl: generated_beg (DO NOT EDIT BELOW) reg dbuf_rd_valid; always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin dbuf_rd_valid <= 'b0; end else begin dbuf_rd_valid <= dbuf_rd_en_new; end end reg [8-1:0] rd_data_mask; //which data to be fetched by sdp. wire [8-1:0] rd_data_mask_pre; assign rd_data_mask_pre = cacc2sdp_valid & cacc2sdp_ready ? {rd_data_mask[8-2:0],rd_data_mask[8-1]} : rd_data_mask; always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin rd_data_mask <= 'b1; end else begin rd_data_mask <= rd_data_mask_pre; end end wire [8-1:0] data_left_mask_pre = dbuf_rd_en_new ? {8{1'b1}} : (cacc2sdp_valid & cacc2sdp_ready) ? (data_left_mask<<1'b1) : data_left_mask; always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin data_left_mask <= 'b0; end else begin data_left_mask <= data_left_mask_pre; end end //| eperl: generated_end (DO NOT EDIT ABOVE) wire cacc2sdp_valid = (|data_left_mask); wire dbuf_rd_ready = ~(|data_left_mask); //: my $t1=""; //: my $kk= 32*1; //: print "wire [${kk}-1:0] cacc2sdp_pd_data= "; //: for (my $i=0; $i<(32*8)/(32*1); $i++){ //: $t1 .= "dbuf_rd_data[($i+1)*${kk}-1:$i*${kk}]&{${kk}{rd_data_mask[${i}]}} |"; //: } //: my $t2= "{${kk}{1'b0}}"; //: print "$t1"."$t2".";\n"; //| eperl: generated_beg (DO NOT EDIT BELOW) wire [32-1:0] cacc2sdp_pd_data= dbuf_rd_data[(0+1)*32-1:0*32]&{32{rd_data_mask[0]}} |dbuf_rd_data[(1+1)*32-1:1*32]&{32{rd_data_mask[1]}} |dbuf_rd_data[(2+1)*32-1:2*32]&{32{rd_data_mask[2]}} |dbuf_rd_data[(3+1)*32-1:3*32]&{32{rd_data_mask[3]}} |dbuf_rd_data[(4+1)*32-1:4*32]&{32{rd_data_mask[4]}} |dbuf_rd_data[(5+1)*32-1:5*32]&{32{rd_data_mask[5]}} |dbuf_rd_data[(6+1)*32-1:6*32]&{32{rd_data_mask[6]}} |dbuf_rd_data[(7+1)*32-1:7*32]&{32{rd_data_mask[7]}} |{32{1'b0}}; //| eperl: generated_end (DO NOT EDIT ABOVE) //layer_end handle reg dbuf_rd_layer_end_latch; wire dbuf_rd_layer_end_latch_w = dbuf_rd_layer_end? 1'b1 : ~(|data_left_mask) ? 1'b0 : dbuf_rd_layer_end_latch; //: &eperl::flop("-q dbuf_rd_layer_end_latch -d dbuf_rd_layer_end_latch_w -nodeclare"); //| eperl: generated_beg (DO NOT EDIT BELOW) always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin dbuf_rd_layer_end_latch <= 'b0; end else begin dbuf_rd_layer_end_latch <= dbuf_rd_layer_end_latch_w; end end //| eperl: generated_end (DO NOT EDIT ABOVE) ////regout to SDP ////: my $kk=CACC_SDP_DATA_WIDTH; ////: &eperl::flop("-q cacc2sdp_valid -d cacc2sdp_valid_w"); ////: &eperl::flop("-wid ${kk} -q cacc2sdp_pd_data -d cacc2sdp_pd_data_w"); wire last_data; wire cacc2sdp_batch_end = 1'b0; wire cacc2sdp_layer_end = dbuf_rd_layer_end_latch&last_data&cacc2sdp_valid&cacc2sdp_ready; //data_left_mask=0; assign cacc2sdp_pd[32*1 -1:0] = cacc2sdp_pd_data; assign cacc2sdp_pd[32*1 +2 -2] = cacc2sdp_batch_end; assign cacc2sdp_pd[32*1 +2 -1] = cacc2sdp_layer_end; // generate CACC done interrupt wire [1:0] cacc_done_intr_w; reg intr_sel; wire cacc_done = cacc2sdp_valid & cacc2sdp_ready & cacc2sdp_layer_end; assign cacc_done_intr_w[0] = cacc_done & ~intr_sel; assign cacc_done_intr_w[1] = cacc_done & intr_sel; wire intr_sel_w = cacc_done ? ~intr_sel : intr_sel; //: &eperl::flop("-nodeclare -q intr_sel -d \"intr_sel_w \" -clk nvdla_core_clk -rst nvdla_core_rstn "); //: &eperl::flop(" -q cacc_done_intr -d \"cacc_done_intr_w \" -wid 2 -clk nvdla_core_clk -rst nvdla_core_rstn "); //| eperl: generated_beg (DO NOT EDIT BELOW) always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin intr_sel <= 'b0; end else begin intr_sel <= intr_sel_w ; end end reg [1:0] cacc_done_intr; always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin cacc_done_intr <= 'b0; end else begin cacc_done_intr <= cacc_done_intr_w ; end end //| eperl: generated_end (DO NOT EDIT ABOVE) assign cacc2glb_done_intr_pd = cacc_done_intr; ///// generate credit signal assign accu2sc_credit_size = 3'h1; assign last_data = (data_left_mask=={1'b1,{(32*8)/(32*1)-1{1'b0}}}); //: &eperl::flop(" -q accu2sc_credit_vld -d \"cacc2sdp_valid & cacc2sdp_ready & last_data\" -clk nvdla_core_clk -rst nvdla_core_rstn -rval 0"); //| eperl: generated_beg (DO NOT EDIT BELOW) reg accu2sc_credit_vld; always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin accu2sc_credit_vld <= 'b0; end else begin accu2sc_credit_vld <= cacc2sdp_valid & cacc2sdp_ready & last_data; end end //| eperl: generated_end (DO NOT EDIT ABOVE) // spyglass enable_block NoWidthInBasedNum-ML endmodule // NV_NVDLA_CACC_delivery_buffer