`default_nettype none
module insert_at
#( int wa = 20, wb = 10, wo = wa+wb, walg = $clog2(wa+1) )
( output logic [wo-1:0] o,
input uwire [wa-1:0] ia,
input uwire [wb-1:0] ib,
input uwire [walg-1:0] pos );
:Example:
uwire [wa-1:0] mask_low;
mask_lsb #(wa) ml(mask_low, pos);
uwire [wa-1:0] ia_low = ia & mask_low;
uwire [wa-1:0] ia_high_low = ia & ~mask_low;
000
localparam int wblg = $clog2(wb);
uwire [wo-1:0] ia_high;
shift_left #(wa,wo,wblg) slc( ia_high, ia_high_low, wblg'(wb) );
uwire [wo-1:0] ib_at_pos;
shift_left #(wb,wo,walg) slb( ib_at_pos, ib, pos );
assign o = ia_high | ib_at_pos | ia_low;
endmodule
module shift_left
#( int wi = 4, wo = wi, wolg = $clog2(wo) )
( output uwire [wo-1:0] o,
input uwire [wi-1:0] i,
input uwire [wolg-1:0] amt );
assign o = i << amt;
endmodule
module shift_right
#( int wi = 4, wo = wi, wolg = $clog2(wo) )
( output uwire [wo-1:0] o,
input uwire [wi-1:0] i,
input uwire [wolg-1:0] amt );
assign o = i >> amt;
endmodule
module mask_lsb
#( int wo = 6, wp = $clog2(wo+1) )
( output logic [wo-1:0] o, input uwire [wp-1:0] n1 );
always_comb for ( int i=0; i<wo; i++ ) o[i] = i < n1;
endmodule
module mask_msb
#( int wo = 6, wp = $clog2(wo+1) )
( output logic [wo-1:0] o, input uwire [wp-1:0] n1 );
always_comb for ( int i=0; i<wo; i++ ) o[wo-i-1] = i < n1;
endmodule
cadence
module testbench;
logic done [1:-1];
initial done[-1] = 1;
testbench_size #(8,3, "Set 1") tb1(done[0],done[-1]);
testbench_size #(4,5, "Set 2") tb2(done[1],done[0]);
endmodule
module testbench_size
#( int wa = 8, int wb = 3, string label = "set me" )
( output logic done_me,
input uwire logic done_pred );
localparam int wo = wa+wb;
localparam int walg = $clog2(wa+1);
localparam int n_tests = (wa+1) * 3;
logic [wa-1:0] ia;
logic [wb-1:0] ib;
uwire [wo-1:0] o;
logic [walg-1:0] pos;
insert_at #(wa,wb) iat(o, ia, ib, pos);
initial begin
automatic int n_err = 0;
wait ( done_pred === 1 );
for ( int tn = 0; tn < n_tests; tn++ ) begin
automatic int rnd = tn / (wa+1);
logic [wo-1:0] o_shadow;
pos = tn % (wa+1);
case ( rnd )
0: begin ia = -1; ib = 0; end
1: begin ia = 0; ib = -1; end
default: {ia,ib} = {$random};
endcase
#1;
for ( int i=0; i<pos; i++ ) o_shadow[i] = ia[i];
for ( int i=0; i<wb; i++ ) o_shadow[i+pos] = ib[i];
for ( int i=pos; i<wa; i++ ) o_shadow[i+wb] = ia[i];
if ( o_shadow !== o ) begin
n_err++;
if ( n_err < 6 )
$write("Error %s for ia=%b ib=%b pos=%d %b != %b (correct)\n",
label,
ia, ib, pos, o, o_shadow);
end
end
$write("For %s, done with %0d tests, %0d errors found.\n",
label, n_tests, n_err);
done_me = 1;
end
endmodule
cadence