```/// 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

////////////////////////////////////////////////////////////////////////////////
///

/// 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
```