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