Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module TopLevel_tb;
- // To DUT Inputs
- bit start;
- bit CLK;
- // From DUT Outputs
- wire halt; // done flag
- // Instantiate the Device Under Test (DUT)
- TopLevel DUT (
- start ,
- CLK ,
- halt
- );
- logic[63:0] dividend; // fixed for pgm 1 at 64'h8000_0000_0000_0000;
- logic[15:0] divisor1; // divisor 1 (sole operand for 1/x) to DUT
- logic[63:0] quotient1; // internal wide-precision result
- logic[15:0] result1, // desired final result, rounded to 16 bits
- result1_DUT; // actual result from DUT
- logic ov;
- real quotientR; // quotient in $real format
- // program 2 variables
- logic[15:0] div_in2; // dividend 2 to DUT
- logic[ 7:0] divisor2; // divisor 2 to DUT
- logic[23:0] result2, // desired final result, rounded to 24 bits
- result2_DUT; // actual result from DUT
- // program 3 variables
- logic[15:0] dat_in3; // operand to DUT
- logic[ 7:0] dat_out3; // SQRT(operand) from DUT
- logic[47:0] square3; // internal expansion of operand
- logic[ 7:0] result3, // desired 8-bit rounded integer result
- result3_DUT; // actual result from DUT
- real argument, result, // reals used in test bench square root algorithm
- error, result_new;
- always begin // clock period = 10 Verilog time units
- #5ns CLK = 1;
- #5ns CLK = 0;
- end
- initial begin
- // launch program 1
- start = 1;
- // Initialize DUT's data memory
- #10ns
- for(int i=0; i<256; i++) begin
- DUT.data_mem1.core[i] = 8'h0; // clear data_mem
- end
- // students may also pre_load desired constants into data_mem
- // Initialize DUT's register file
- for(int j=0; j<16; j++)
- DUT.reg_file1.registers[j] = 8'b0; // default -- clear it
- DUT.reg_file1.registers[14] = 8'd17;
- DUT.reg_file1.registers[12] = 8'd1;
- DUT.reg_file1.registers[10] = 8'd255;
- DUT.reg_file1.registers[13] = 8'd8;
- DUT.reg_file1.registers[9] = 8'd9;
- DUT.reg_file1.registers[11] = 8'd128;
- // launch program in DUT
- #20ns start = 0;
- dividend = 64'h8000_0000_0000_0000;
- divisor1 = 16'd240; // *** try various values here ***
- div1;
- DUT.data_mem1.core[8] = divisor1[15:8];
- DUT.data_mem1.core[9] = divisor1[ 7:0];
- wait(halt);
- result1_DUT[15:8] = DUT.data_mem1.core[10];
- result1_DUT[ 7:0] = DUT.data_mem1.core[11];
- $display ("divisor = %h, quotient = %h, result1 = %h, equiv to %10.5f", divisor1, quotient1, result1, quotientR);
- $display ("MEM8 = %h, MEM9 = %h", DUT.data_mem1.core[8], DUT.data_mem1.core[9]);
- if(result1==result1_DUT) $display("success -- match1");
- else $display("OOPS1! expected %h, got %h",result1,result1_DUT);
- #10ns $stop;
- //// preload operands and launch program 2
- // #10ns start = 1;
- //// insert dividend and divisor
- // div_in2 = 16'h0501; // *** try various values here ***
- // divisor2 = 8'h53; // *** try various values here ***
- //// *** change names of memory or its guts as needed ***
- // d1.dat_mem1.core[0] = div_in2[15:8];
- // d1.dat_mem1.core[1] = div_in2[ 7:0];
- // d1.dat_mem1.core[2] = divisor2;
- // div2;
- // #20ns start = 0;
- // #20ns wait(done);
- //// *** change names of memory or its guts as needed ***
- // result2_DUT[23:16] = d1.dat_mem1.core[4];
- // result2_DUT[15: 8] = d1.dat_mem1.core[5];
- // result2_DUT[ 7: 0] = d1.dat_mem1.core[6];
- // $display ("dividend = %h, divisor2 = %h, quotient = %h, result2 = %h, equiv to %10.5f",dividend, divisor2, quotient1, result2, quotientR);
- // if(result2==result2_DUT) $display("success -- match2");
- // else $display("OOPS2! expected %h, got %h",result2,result2_DUT);
- //// preload operands and launch program 3
- // #10ns start = 1;
- //// insert operand
- // dat_in3 = 65535; // *** try various values here ***
- //// *** change names of memory or its guts as needed ***
- // d1.dat_mem1.core[13] = dat_in3[15: 8];
- // d1.dat_mem1.core[14] = dat_in3[ 7: 0];
- // div3;
- // #20ns start = 0;
- // #20ns wait(done);
- //// *** change names of memory or its guts as needed ***
- // result3_DUT = d1.dat_mem1.core[15];
- // $display("operand = %h, sqrt = %h",dat_in3,dat_out3);
- // if(dat_out3==result3_DUT) $display("success -- match3");
- // else $display("OOPS3! expected %h, got %h",dat_out3,result3_DUT);
- // #10ns $stop;
- end
- task automatic div1;
- quotient1 = dividend/divisor1;
- result1 = quotient1[63:48]+quotient1[47]; // half-LSB upward rounding
- quotientR = 1.00000/$itor(divisor1);
- endtask
- task automatic div2;
- dividend = div_in2<<48;
- quotient1 = dividend/divisor2;
- result2 = quotient1[63:40]+quotient1[39]; // half-LSB upward rounding
- quotientR = $itor(div_in2)/$itor(divisor2);
- // $display ("dividend = %h, divisor2 = %h, quotient = %h, result2 = %h, equiv to %10.5f",dividend, divisor2, quotient1, result2, quotientR);
- endtask
- task automatic div3;
- argument = $itor(dat_in3);
- // real error, result_new;
- result = 1.0;
- error = 1.0;
- while (error > 0.001) begin
- result_new = argument/2.0/result + result/2.0;
- error = (result_new - result)/result;
- if (error < 0.0) error = -error;
- result = result_new;
- $displayb(result_new,,result);
- end
- {ov,dat_out3} = $rtoi(result+0.5);
- if(ov) dat_out3 = 8'hff;
- endtask
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement