/// EE 4702 Spring 2001 Alternate Homework 2 Solution and Test // Solution to Homework 2 based on student submissions. // Test code used to test student submissions. (metatest_pe_8) //////////////////////////////////////////////////////////////////////////////// /// Problem 1 /// /// Solution to Problem 1 based on student submissions. // module priority_encoder_8_b(grant,request); input request; output grant; wire [7:0] request; reg [7:0] grant; always @( request ) begin grant = 1; while( grant && ! ( grant & request ) ) grant = grant << 1; end endmodule /// Another solution to Problem 1. // // This solution is less desirable since it uses an additional // variable, i, and more lines. // module alternate_priority_encoder_8_b(grant,request); input request; output grant; wire [7:0] request; reg [7:0] grant; always @( request ) begin:MAIN integer i; grant = 0; begin:LOOP1 for(i=0; i<8; i=i+1) if( request[i] ) begin grant[i] = 1'b1; disable LOOP1; end end end endmodule //////////////////////////////////////////////////////////////////////////////// /// Problem 2 /// module priority_encoder_1_es(grant,found_out,request,found_in); output grant, found_out; input request, found_in; wire grant, found_out; wire request, found_in; or #1 o1(found_out, found_in, request); and #1 a1(grant, not_found_in, request); not #1 n1(not_found_in, found_in); endmodule //////////////////////////////////////////////////////////////////////////////// /// Problem 3 /// module priority_encoder_8_es(grant, request); input request; output grant; wire [7:0] request, grant; wire found_out_0, dummy; priority_encoder_4_es pe4_0(grant[3:0],found_out_0, request[3:0],1'b0); priority_encoder_4_es pe4_1(grant[7:4],dummy,request[7:4],found_out_0); endmodule module priority_encoder_4_es(grant, found_out, request, found_in); input request, found_in; output grant, found_out; wire [2:0] found; wire [3:0] grant, request; priority_encoder_1_es pe1_0(grant[0], found[0], request[0], found_in); priority_encoder_1_es pe1_1(grant[1], found[1], request[1], found[0]); priority_encoder_1_es pe1_2(grant[2], found[2], request[2], found[1]); priority_encoder_1_es pe1_3(grant[3], found_out, request[3], found[2]); endmodule //////////////////////////////////////////////////////////////////////////////// /// Problem 4 /// // Solution based on student submissions. module test_pe_8(done, okay_b, okay_es, start); output done, okay_b, okay_es; input start; reg done, okay_b, okay_es; integer i; wire [7:0] request = i[7:0]; wire [7:0] grant_b, grant_es; priority_encoder_8_b peb(grant_b,request); priority_encoder_8_es pees(grant_es,request); initial done = 0; always begin:MAIN integer pos; wait( start ); done = 0; wait( !start ); okay_b = 1; okay_es = 1; for( pos = 0; pos <= 8; pos = pos + 1 ) begin:POS_LOOP reg [7:0] start; integer incr; start = 1 << pos; incr = 1 << ( pos + 1 ); for( i = start; i < 256; i = i + incr ) #25 begin if( grant_b !== start ) okay_b = 0; if( grant_es !== start ) okay_es = 0; end end // block: POS_LOOP // Use if statement to turn on messages when debugging. if( 0 ) begin $display("Test over, behavioral model %s", okay_b ? "passed" : "failed"); $display("Test over, structural model %s", okay_es ? "passed" : "failed"); end done = 1; end // block: MAIN endmodule // test_pe_8 //////////////////////////////////////////////////////////////////////////////// /// Grading Modules /// /// A priority encoder module that can be set to fail in particular ways. // // Used to test testbenches. module t_priority_encoder_8_b(grant,request); input request; output grant; wire [7:0] request; reg [7:0] grant; function [7:0] r_pot; input dummy; r_pot = 1 << ( $random & 7 ); endfunction always @( request or metatest_pe_8.fault ) begin:MAIN integer i; reg [7:0] old_grant; grant = 8'b0; begin:LOOP1 for(i=0; i<8; i=i+1) if( request[i] ) begin grant[i] = 1'b1; disable LOOP1; end end if( metatest_pe_8.fault_at[request] && metatest_pe_8.fault ) begin old_grant = grant; while( old_grant === grant ) case( metatest_pe_8.fault ) 0: $stop; 1: grant = r_pot(1); 2: grant = old_grant | r_pot(1); 3: grant = old_grant | r_pot(1) | r_pot(1); 4: if( request == 0 ) begin grant = 1; old_grant = 0; end else begin grant = 0; old_grant = 1; end 5: grant = old_grant ^ 8'bx0000000; 6: $stop; endcase end end endmodule module t_priority_encoder_8_es(grant, request); input request; output grant; wire [7:0] request, grant; wire found_out_0, dummy; t_priority_encoder_8_b pe(grant,request); endmodule /// Meta-Testbench // // Runs submitted testbenches multiple times, changing the kinds // of faults in the priority encoder modules. module metatest_pe_8(); wire done, ok_b, ok_es; reg start; integer fault; integer okays_b[0:4]; // Bit vector specifying which requests should generate an incorrect output. reg [255:0] fault_at; integer fault_density; test_pe_8 tpe8(done, ok_b, ok_es, start); initial begin for( fault_density = 0; fault_density < 5; fault_density = fault_density + 1 ) begin:A case( fault_density ) 0: fault_at = 1; 1: fault_at = 1<<200; 2: fault_at = 1<<255; // Five faults. 3: fault_at = 256'h10001000801000000000000000000000000000000000002000; // 128 faults 4: fault_at = 256'h131dc062bab2b48e50f5abd4fc1e0a2abd54a5053ed4d181079afcee0a8f78ef; endcase // case( fault_density ) for( fault = 0; fault < 6; fault = fault + 1 ) begin start = 1; wait( done === 0 ); // Wait from 0 to 3 cycles, randomly chosen. #( $random & 3 ); start = 0; wait( done === 1 ); if( ( fault == 0 ) !== ok_b ) begin $display("GR OUTC: FAIL (den,ty) (%d,%d)", fault_density,fault); disable A; end // Wait from 0 to 3 cycles, randomly chosen. #( $random & 3 ); end // for ( fault = 0; fault < 6; fault = fault + 1 ) $display("GR OUTC: PASS (den) %d",fault_density); end // block: A $display("Done with test."); end // initial begin endmodule // metatest_pe_8