reg tristate;
begin
tristate = `false;
if ( cycle_end && cycle_start ) begin
current_phase = p_idle;
enabled = `false;
cycle_end = `true;
cycle_start = `false;
daddress = `false;
last_transfer = `true;
cycle_count = 0;
devsel_count = 0;
data_phase_complete = `true;
devsel_asserted = `false;
stop_count = 0;
termination = no_termination;
end // if // cycle end
if ( data_phase_complete ) begin
irdy_asserted = `false;
trdy_asserted = `false;
irdy_count = 0;
trdy_count = 0;
irdy_wait = 0;
trdy_wait = 0;
end // if
temp = $time/`time_scale_multiplier;
if (trace_enable) $fdisplay(fo,"======================");
if (trace_enable) $fdisplay(fo,"TIME (NS) : %0d",temp);
if ( INP.reqnn !== last_req ) begin
if (trace_enable) $fdisplay(fo,"REQ[7:0] : %h",INP.reqnn);
end // if
if ( INP.gntnn !== last_gnt ) begin
if (trace_enable) $fdisplay(fo,"GNT[7:0] : %h",INP.gntnn);
end // if
if ( INP.reqnn === 8'hFF && INP.gntnn === 8'hFB && INP.irdynn !== 1'b0 && INP.trdynn !== 1'b0 ) begin
park_cnt = park_cnt + 1;
if ( park_cnt > 1 ) begin
if ( ((par === 1'b0 || par === 1'b1) && cpa && cpc) ) begin
if (trace_enable) $fdisplay(fo,"Bus parking : 3 Parity Stable");
end // if
tmp = ^(INP.ad[31 : 0]);
if ( tmp === 1'b0 || tmp === 1'b1 ) begin
if (trace_enable) $fdisplay(fo,"Bus parking : 1 AD Stable");
cpa = `true;
parking = `true;
end // if
tmp = ^(INP.cxbenn[3 : 0]);
if ( tmp === 1'b0 || tmp === 1'b1 ) begin
if (trace_enable) $fdisplay(fo,"Bus parking : 2 CXBE Stable");
cpc = `true;
end // if
end // if
end else begin
park_cnt = 0;
cpa = `false;
cpc = `false;
end // if
if ( INP.reqnn === 8'hFF && INP.gntnn === 8'hFF && parking ) begin
if (par === 1'bz) begin
if (trace_enable) $fdisplay(fo,"Bus parking : 6 Parity Tristated");
parking = `false;
end // if
tristate = `true;
begin : loop1
for (i = 0; i <= 31; i = i + 1) begin
if ( ad[i] !== 1'bz ) begin
tristate = `false;
disable loop1; // exit
end // if
end // loop
end // loop1
if ( tristate ) begin
if (trace_enable) $fdisplay(fo,"Bus parking : 4 AD Tristated");
end // if
tristate = `true;
begin : loop2
for (i = 0; i <= 3; i = i + 1) begin
if ( cxbenn[i] !== 1'bz ) begin
tristate = `false;
disable loop2; // exit
end // if
end // loop
end // loop2
if ( tristate ) begin
if (trace_enable) $fdisplay(fo,"Bus parking : 5 CXBE Tristated");
end // if
end // if
if ( INP.framenn === 1'b0 && (last_frame === 1'b1 || relatch) && cycle_end ) begin
byte_en = INP.cxbenn;
command = INP.cxbenn[3 : 0];
icommand = command;
current_phase = p_address;
begin : loop5
for (i = 0; i <= 7; i = i + 1) begin
if ( last_gnt[i] === 1'b0 ) begin
current_ignt = i;
disable loop5; // exit
end // if
end // loop
end // loop5
if ( relatch ) begin
address[63 : 32] = INP.ad[31 : 0];
iaddr10 = address[1 : 0];
end else begin
address[31 : 0] = INP.ad[31 : 0];
iaddr10 = address[1 : 0];
end // if
if ( icommand === 13 ) begin // DUAL address cycle
if ( daddress ) begin
error_report(30); // Dual Command 1101 not valid after dual command : cycle ignored
daddress = `false;
cycle_end = `true;
end else begin
relatch = `true; // latch address/command next clock
daddress = `true;
if (trace_enable) $fdisplay(fo,"Command : %s",cycle_str[icommand]);
end // if
end else begin
if ( INP.req64nn === 1'b0 ) begin
master_req_size = 64;
end else begin
master_req_size = 32;
end // if
slave_ack_size = 32;
fast_back2back = `false;
cycle_locked = `false;
relatch = `false;
cycle_start = `true;
ignore_cycle = `false;
cycle_end = `false;
last_transfer = `false;
speed = none;
frame_count = 0;
cycle_count = 1;
devsel_count = 0;
irdy_count = 0;
irdy_wait = 0;
trdy_count = 0;
trdy_wait = 0;
stop_count = 0;
transfer_count = 0;
termination = no_termination;
cycle_status = pass;
memory_cmd = `false;
irdy_asserted = `false;
trdy_asserted = `false;
stop_asserted = `false;
devsel_asserted= `false;
if (!daddress) begin
address[63 : 32] = 32'h00000000;
end // if
if (trace_enable) $fdisplay(fo,"Command : %s",cycle_str[icommand]);
if ( (icommand === 6 || icommand === 7 || icommand === 12 ||
icommand === 14 || icommand === 15) ) begin
if (trace_enable) $fdisplay(fo,"Burst Order : %s",addr_str[iaddr10]);
memory_cmd = `true;
end // if
if ( icommand === 10 || icommand === 11 ) begin
if (trace_enable) $fdisplay(fo,"IDSEL[7:0] : %h",(INP.idsel));
end // if
if ( daddress ) begin
if (trace_enable) $fdisplay(fo,"Address (DAC) : %h",(address[63 : 0]));
end else begin
if (trace_enable) $fdisplay(fo,"Address (SAC) : %h",(address[31 : 0]));
end // if
if (trace_enable) $fdisplay(fo,"Master size : %0d",master_req_size);
begin : loop6
for (i = 0; i <= 7; i = i + 1) begin
tmp_last_cycle = last_cycle[i];
if ( tmp_last_cycle[127:96] === current_ignt ) begin
if ( tmp_last_cycle[128] ) begin
if ( icommand !== tmp_last_cycle[31:0] || address !== tmp_last_cycle[95:32]) begin
error_report(48); // Current cycle is not the same as previous cycle terminated by retry (WARNING).
end // if
tmp_last_cycle[128] = `false;
last_cycle[i] = tmp_last_cycle;
end else begin disable loop6; // exit
end // if
end // if
end // loop
end // loop6
end // if
end else if ( INP.framenn === 1'b1 && relatch ) begin
error_report(31); // Frame must remain asserted for cycle following dual command : cycle ignored
relatch = `false;
daddress = `false;
cycle_end = `true;
end // if
if ( cycle_start ) begin
if ( cycle_count === 2 ) begin
if ( command[0] === 1'b0 ) begin
current_phase = p_tar;
end else begin
current_phase = p_data;
end // if
end else if ( cycle_count > 2 ) begin
current_phase = p_data;
end // if
cycle_count = cycle_count + 1;
if ( termination === no_termination ) begin
data_phase_complete = `false;
end // if
if ( INP.devselnn === 1'b0 ) begin
devsel_asserted = `true;
devsel_count = devsel_count + 1;
if ( last_devsel === 1'b1 ) begin // Determine slave decode speed on devsel assertion
case ( cycle_count )
2 : begin error_report(32); // Devsel asserted during address phase
end
3 : begin speed = fast_speed;
end
4 : begin speed = medium_speed;
end
5 : begin speed = slow_speed;
end
6 : begin speed = subtractive_speed;
end
default begin /* null */
end
endcase
if ( daddress ) begin
if (model_flags.debug_level > 0) begin
$display("NOTE at %0t from %m",$time);
$display(" \"Command = %s Address (DAC) = %h\"",cycle_str[icommand],address[63:0]);
end
if (model_flags.debug_level < 0) begin
$fdisplay(fo,"Command = %s",cycle_str[icommand]);
$fdisplay(fo,"Address (DAC) = %h",address[63:0]);
end
end else begin
if (model_flags.debug_level > 0) begin
$display("NOTE at %0t from %m",$time);
$display(" \"Command = %s Address (SAC) = %h\"",cycle_str[icommand],address[31:0]);
end
if (model_flags.debug_level < 0) begin
$fdisplay(fo,"=========================================");
$fdisplay(fo,"TIME (NS) : %0d",temp);
$fdisplay(fo,"Command : %s",cycle_str[icommand]);
$fdisplay(fo,"Address (SAC) : %h",address[31:0]);
end
end // if
irdy_count = 0;
trdy_count = 0;
irdy_burst = 0;
trdy_burst = 0;
if ( INP.ack64nn === 1'b0 ) begin
slave_ack_size = 64;
end // if
if (trace_enable) $fdisplay(fo,"Speed : %s",speed_str[speed]);
if (trace_enable) $fdisplay(fo,"Target size : %0d",slave_ack_size);
end // if
end else if ( INP.devselnn === 1'b1 ) begin
if ( last_devsel === 1'b0 ) begin
if ( devsel_count === 0 ) begin
fast_back2back = `true;
end // if
end // if
end else begin // Devsel unknown during cycle
error_report(34); // Devsel UNKNOWN during cycle: Ignored
end // if
if ( INP.framenn === 1'b0 ) begin
frame_count = frame_count + 1;
if ( INP.irdynn !== 1'b0 && last_frame === 1'b0 ) begin
master_data_latency = master_data_latency + 1;
end else if ( last_frame !== 1'b0 ) begin
master_data_latency = 0;
end // if
if ( INP.trdynn !== 1'b0 && last_frame === 1'b0 ) begin
slave_data_latency = slave_data_latency + 1;
end else if ( last_frame !== 1'b0 ) begin
slave_data_latency = 0;
end // if
end else if ( INP.framenn === 1'b1 ) begin // Frame negated during cycle
last_transfer = `true;
if ( speed === none ) begin
if ( (cycle_count >= 6) ) begin // No Devsel
termination = master_abort; // Master Initiated termination (master abort)
cycle_end = `true;
data_phase_complete = `true;
end else if ( (INP.irdynn === 1'b1) ) begin
// termination := master_timeout; -- Master Initiated termination (master timeout)
cycle_end = `true;
data_phase_complete = `true;
end // if
end // if
if ( termination !== no_termination ) begin
cycle_end = `true;
end // if
if ( last_frame === 1'b0 && INP.irdynn === 1'b1 ) begin
master_data_latency = master_data_latency + 1;
end // if
if ( ! data_phase_complete && INP.trdynn === 1'b1 ) begin
slave_data_latency = slave_data_latency + 1;
end // if
end // if
if ( INP.irdynn === 1'b0 && INP.trdynn === 1'b0 ) begin
data_phase_complete = `true;
transfer_count = transfer_count + 1;
if ( INP.locknn === 1'b0 ) begin
cycle_locked = `true;
end // if
data_burst = INP.ad;
irdy_burst = irdy_wait;
trdy_burst = trdy_wait;
if (trace_enable) $fdisplay(fo,"Transfer Count : %0d",transfer_count);
if (trace_enable) $fdisplay(fo,"Irdy waits : %0d",irdy_burst);
if (trace_enable) $fdisplay(fo,"Trdy waits : %0d",trdy_burst);
byte_en = INP.cxbenn;
if ( slave_ack_size === 64 ) begin
if (trace_enable) $fdisplay(fo,"C/BE[7:0] : %h",(byte_en));
if (trace_enable) $fdisplay(fo,"Data Transfered : %h",(data_burst));
if (!(model_flags.debug_level===0)) begin
$display("NOTE at %0t from %m",$time);
$display(" \"C/BE[7:0] = %h Data = %h\"",byte_en,data_burst);
end
end else begin
if (trace_enable) $fdisplay(fo,"C/BE[3:0] : %h",(byte_en[3 : 0]));
if (trace_enable) $fdisplay(fo,"Data Transfered : %h",(data_burst[31 : 0]));
if (!(model_flags.debug_level===0)) begin
$display("NOTE at %0t from %m",$time);
$display(" \"C/BE[3:0] = %h Data = %h\"",byte_en[3:0],data_burst[31:0]);
end
end // if
if ( last_transfer ) begin // Master Initiated termination (Normal)
cycle_end = `true;
data_phase_complete = `true;
if ( termination === no_termination ) begin
termination = completion;
end // if
end // if
end // if
if (icommand === special_cycle && cycle_count === 3) begin
data_burst = INP.ad;
if (trace_enable) $fdisplay(fo,"Data Transfered : %h",(data_burst[31 : 0]));
transfer_count = 0;
data_phase_complete = `true;
speed = no_speed;
end // if
if ( INP.trdynn === 1'b0 ) begin
trdy_asserted = `true;
trdy_count = trdy_count + 1;
end else if ( INP.trdynn === 1'b1 && devsel_count > 0 ) begin
trdy_wait = trdy_wait + 1;
end // if
if ( INP.irdynn === 1'b0 ) begin
irdy_asserted = `true;
irdy_count = irdy_count + 1;
end else if ( INP.irdynn === 1'b1 ) begin
if ( (cycle_count > 2) ) begin
irdy_wait = irdy_wait + 1;
end // if
end // if
// Check for target initiated termination
if ( INP.stopnn === 1'b0 ) begin
stop_asserted = `true;
stop_count = stop_count + 1;
// missing error_report(15) : if ( INP.framenn === 1'b1 ) begin
if ( INP.trdynn === 1'b1 && last_trdy === 1'b0 && last_irdy === 1'b1 ) begin
data_phase_complete = `false;
end else if ( INP.framenn === 1'b1 ) begin
data_phase_complete = `true;
end // if
if ( last_stop === 1'b1 ) begin
if ( INP.devselnn === 1'b0 ) begin
if ( INP.irdynn === 1'b0 && INP.trdynn === 1'b0 ) begin
if ((termination === completion) && (transfer_count === 1)) begin
termination = mct;
end else
termination = disconnect_b;
end else if ( INP.irdynn === 1'b1 && INP.trdynn === 1'b0 ) begin
termination = disconnect_a;
end else if ( INP.trdynn === 1'b1 ) begin
termination = disconnect_c;
if ( transfer_count === 0 ) begin // Retry (special case of Disconnect -C)
tmp_last_cycle = last_cycle[current_ignt];
tmp_last_cycle[31:0] = icommand;
tmp_last_cycle[95:32] = address;
tmp_last_cycle[127:96] = current_ignt;
tmp_last_cycle[128] = `true;
last_cycle[current_ignt] = tmp_last_cycle;
end // if
end // if
end else if ( INP.devselnn === 1'b1 ) begin
termination = target_abort;
data_phase_complete = `true;
cycle_end = `true;
end // if
end // if
end // if
end // if // cycle start
if ( INP.locknn === 1'b0 ) begin
if (trace_enable) $fdisplay(fo,"LOCK : 0 Asserted");
end // if
if ( ((last_phase === p_address || last_phase === p_data) && check_parity) ) begin
if ( INP.par !== parity ) begin
if (trace_enable) $fdisplay(fo,"Parity : ",parity,",",INP.par);
parity_error = `true;
end // if
if ( last_phase === p_data && INP.par64 !== parity64 && slave_ack_size === 64 ) begin
if (trace_enable) $fdisplay(fo,"Parity64 : ",parity64,",",INP.par64);
parity_error = `true;
end // if
end // if
if ( INP.perrnn === 1'b0 ) begin
if (trace_enable) $fdisplay(fo,"PERR : 0 Asserted");
end // if
if ( INP.serrnn === 1'b0 ) begin
if (trace_enable) $fdisplay(fo,"SERR : 0 Asserted");
end // if
if ( cycle_end && cycle_start ) begin
if (trace_enable) $fdisplay(fo,"Termination : %s",term_str[termination]);
end // if // cycle end
if ( current_phase === p_data || current_phase === p_address ) begin
if ( ad[0] === 1'bz && ad[15] === 1'bz && ad[16] === 1'bz && ad[31] === 1'bz ) begin // See if AD is tristated
check_parity = `false;
end // if
if ( (INP.irdynn === 1'b0 && INP.trdynn === 1'b0) || current_phase === p_address || icommand === 1 ) begin // Check parity during special
check_parity = `true;
parity = ^(INP.cxbenn[3 : 0]) ^ ^(INP.ad[31 : 0]);
parity64 = ^(INP.cxbenn[7 : 4]) ^ ^(INP.ad[63 : 32]);
end else begin
check_parity = `false;
end // if
end // if
last_phase = current_phase;
end
endtask // monitor;
// Check for error conditions
task analyze;
begin
// report parity errors
if ( parity_error ) begin
error_report(38); // Parity error detected
parity_error = `false;
end // if
// Check for Arbitration Errors
if ( last_frame === 1'b1 && INP.framenn === 1'b0 && &(last_gnt) !== 1'b0 ) begin
error_report(39); // Cycle must not start unless GNT asserted (3.4.1)
end // if
gnt_cnt = 0;
for (i = 0; i <= 7; i = i + 1) begin
if ( INP.gntnn[i] === 1'b0 ) begin
gnt_cnt = gnt_cnt + 1;
end else if ( INP.gntnn[i] === 1'bx ) begin
// GNT(I) unknown
end // if
end // loop
case ( gnt_cnt )
1 : begin
// if inp.gnt /= last_gnt and last_gnt /= b"11111111" and state = IDLE then
// error_report(); -- One Clock delay required between GNTs during IDLE (3.4.1)
// end if;
end
default begin
if ( gnt_cnt > 1 ) begin
error_report(1); // Only one GNT allowed asserted at a time (3.4.1)
end // if
end
endcase
if ( spclk === 1 ) begin
spclk = 0;
if ( INP.par !== 1'b1 && INP.par !== 1'b0 ) begin
error_report(35); // par must be stable within 9 clocks of gnt assertion.
end // if
end // if
if ( gclk === 1 ) begin
if ( is_z_cxbenn(cxbenn[3 : 0]) && is_z_ad(ad[31 : 0]) ) begin
gclk = 0;
end // if
if ( gclk !== 0 ) begin
// error_report(36); -- CBE and AD must be tristated within one PCI clock after gnt deasserted.
end // if
gclk = 0;
end // if
if ( sclk > 0 ) begin
if ( current_phase === p_idle ) begin
sclk = sclk + 1;
if ( ! (is_z_cxbenn(cxbenn[3 : 0]) && is_z_ad(ad[31 : 0])) ) begin
sclk = 0;
end // if
if ( sclk === 8 ) begin
error_report(37); // CBE and AD must be stable within 8 clocks of gnt assertion.
spclk = 1;
end // if
end else begin
sclk = 0;
end // if
end // if
if ( INP.gntnn !== last_gnt ) begin
gclk = 1;
if ( gnt_cnt === 1 ) begin
sclk = 1;
end // if
end // if
if ( cycle_count === 2 ) begin // Address phase
if ( master_req_size === 64 ) begin
if ( address[2] !== 1'b0 ) begin
error_report(2); // AD2 must be 0 during address phase of 64 bit transaction.
end // if
if ( ! memory_cmd ) begin
error_report(3); // Only memory commands make sense during 64-bit transfers.
end // if
end // if
end // if
if ( last_frame === 1'b1 && INP.framenn === 1'b1 && current_phase === p_idle) begin
if (INP.stopnn !== 1'b1) begin
error_report(4); // Stop must be deasserted the cycle following frame negation.
end // if
if (INP.trdynn !== 1'b1) begin
error_report(49); // Trdy must be deasserted the cycle following the completion of the last data phase.
end // if
if (INP.devselnn !== 1'b1) begin
error_report(50); // Devsel must be deasserted the cycle following the completion of the last data phase.
end // if
end // if
if (last_stop === 1'b0 && INP.framenn === 1'b0 && INP.irdynn === 1'b0) begin
error_report(51); // FRAME# must be deasserted whenever STOP# is asserted, as soon as IRDY# is asserted (3.3.3.2.1) (RULE 5)
end
if ( cycle_count === 3 ) begin
if ( INP.trdynn === 1'b0 && command[0] === 1'b0 ) begin
error_report(5); // trdy must be deasserted during turnaround cycle on a read.
end // if
end // if
if ( current_phase === p_data ) begin
if ( devsel_count === 0 ) begin
if ( INP.stopnn === 1'b0 || INP.trdynn === 1'b0 ) begin
error_report(6); // target must issue devsel before any other response.
end // if
end // if
if ( INP.framenn === 1'b1 && last_frame === 1'b0 && irdy_count === 0 ) begin
error_report(7); // Frame cannot be deasserted before Irdy is asserted.
end // if
if ( (INP.framenn === 1'b0 && last_frame === 1'b1 && ! (cycle_end || termination === target_abort) && devsel_count > 0) ) begin
error_report(12); // Once Frame is deasserted it cannot be reasserted during the same transaction.
end // if
if ( INP.stopnn === 1'b1 && last_stop === 1'b0 && INP.framenn !== 1'b1 ) begin
error_report(23); // once stop asserted it must stay until frame negated.
end // if
if ( INP.framenn === 1'b1 && last_frame === 1'b0 && INP.irdynn !== 1'b0 ) begin
error_report(24); // Irdy must always be asserted on the first clock edge that frame is neagted.
end // if
end // if
if ( (icommand === 2 || icommand === 3) && devsel_count > 0 && termination === no_termination && transfer_count <= 1 ) begin
if ( (INP.cxbenn[3 : 0] !== 4'hf) && ((iaddr10 === 0 && INP.cxbenn[0] !== 1'b0) ||
(iaddr10 === 1 && (INP.cxbenn[1] !== 1'b0 || INP.cxbenn[0] !== 1'b1)) ||
(iaddr10 === 2 && (INP.cxbenn[2] !== 1'b0 || INP.cxbenn[1] !== 1'b1 || INP.cxbenn[0] !== 1'b1)) ||
(iaddr10 === 3 && (INP.cxbenn[3] !== 1'b0 || INP.cxbenn[2] !== 1'b1 || INP.cxbenn[1] !== 1'b1 || INP.cxbenn[0] !== 1'b1))) ) begin
byte_en = INP.cxbenn;
if ( slave_ack_size === 64 ) begin
if (trace_enable) $fdisplay(fo,"C/BE[7:0] : %h",(byte_en));
end else begin
if (trace_enable) $fdisplay(fo,"C/BE[3:0] : %h",(byte_en[3 : 0]));
end // if
error_report(8); // Illegal combination of AD and C/BE for IO cycle.
end // if
end // if
if ( devsel_count === 1 ) begin
if ( (icommand === 4 || icommand === 5 || icommand === 8 || icommand === 9) ) begin
error_report(9); // Targets must not respond to reserved encodings.
end // if
if ( icommand === 1 ) begin
error_report(10); // Targets must not respond to special cycle.
end // if
if ( (iaddr10 !== 0 && iaddr10 !== 1) && (icommand === 10 || icommand === 11) ) begin
error_report(11); // Targets must not respond to Configuration cycle unless selected.
end // if
end // if
if ( ! data_phase_complete ) begin
if ( irdy_asserted && irdy_count > 1 ) begin
if ( (INP.framenn !== 1'b0 && last_frame === 1'b0) ) begin
error_report(13); // Once irdy asserted frame cannot change until data phase completes.
end // if
end // if
if ( irdy_asserted && INP.irdynn !== 1'b0 ) begin
error_report(14); // Once irdy asserted irdy cannot change until data phase completes.
end // if
if ( INP.trdynn === 1'b0 ) begin
if ( (INP.devselnn !== 1'b0 && last_devsel === 1'b0) ) begin
error_report(16); // Once trdy asserted devsel cannot change until data phase completes.
end // if
if ( (INP.stopnn !== 1'b0 && last_stop === 1'b0) ) begin
error_report(17); // Once trdy asserted stop cannot change until data phase completes.
end // if
end else if ( last_trdy === 1'b0 && trdy_count > 0 ) begin
error_report(15); // Once trdy asserted trdy cannot change until data phase completes.
end // if
if ( INP.stopnn === 1'b0 && last_stop === 1'b0 ) begin
if ( (INP.devselnn !== 1'b0 && last_devsel === 1'b0) ) begin
error_report(21); // Once stop asserted devsel cannot change until data phase completes.
end // if
if ( (INP.trdynn !== last_trdy) ) begin
error_report(20); // Once stop asserted trdy cannot change until data phase completes.
end // if
end // if
if ( INP.stopnn === 1'b1 && last_stop === 1'b0 && stop_count > 0 ) begin
error_report(22); // Once stop asserted stop cannot change until data phase completes.
end // if
end // if
if ( termination === target_abort ) begin
if ( devsel_count === 0 ) begin
error_report(18); // Devsel must be asserted for 1 or more clocks before target abort can be signaled.
end // if
if ( INP.trdynn !== 1'b1 ) begin
error_report(19); // Trdy must be deasserted before target abort can be signaled.
end // if
end // if
if ( termination === master_abort && devsel_count > 0 ) begin
error_report(25); // if devsel asserted master abort termination is not permissible.
end // if
if ( ! cycle_end && termination !== target_abort ) begin
if ( INP.devselnn === 1'b1 && last_devsel === 1'b0 && devsel_asserted ) begin
error_report(26); // once a target has asserted devsel it must not be deasserted before last data phase completes.
end // if
begin : loop7
for (i = 0; i <= 3; i = i + 1) begin
if ( INP.cxbenn[i] === 1'bz ) begin
error_report(27); // C/BE buffers must remain enabled until end.
disable loop7; // exit
end // if
if ( INP.cxbenn[i] === 1'bx && cycle_count > 1 ) begin
error_report(28); // C/BE buffers must be valid during data phase.
disable loop7; // exit
end // if
end // loop
end // loop7
if ( command[0] === 1'b0 && INP.devselnn === 1'b0 ) begin
begin : loop8
for (i = 0; i <= 31; i = i + 1) begin
if ( INP.ad[i] === 1'bz ) begin
error_report(29); // AD buffers must remain enabled until end.
disable loop8; // exit
end // if
end // loop
end // loop8
end // if
end // if
if ( termination === no_termination && devsel_asserted && INP.devselnn === 1'b1 ) begin
error_report(33); // Devsel negated before cycle completion : Ignored
end // if
// Check for data latencies (2.1 Spec)
if ( master_latency_error ) begin
error_report(44); // IRDY# not asserted within 8 clocks of data phase.
master_latency_error = `false;
end // if
if ( ((INP.framenn === 1'b1) || INP.irdynn === 1'b0) ) begin
master_data_latency = 0;
end // if
if ( ((master_data_latency === 8 && transfer_count === 0) || (master_data_latency === 9 && transfer_count > 0)) ) begin
master_latency_error = `true;
end // if
if ( slave_latency_error ) begin
error_report(47); // TRDY# not asserted within 16 clocks of initial data phase.
slave_latency_error = `false;
end // if
if ( ((slave_data_latency === 16 && transfer_count === 0)) ) begin
slave_latency_error = `true;
end // if
if ( (INP.trdynn === 1'b0) ) begin
slave_data_latency = 0;
end // if
// Check for addressing errors and C/BE# errors
if ( current_phase === p_address ) begin
if ( icommand === 15 && (INP.ad[1] !== 1'b0 || INP.ad[0] !== 1'b0) ) begin
error_report(45); // Linear Burst Ordering must be used for Memory Write Invalidate cycles;
end // if
end else if ( current_phase === p_data ) begin
if ( (((INP.cxbenn[0] !== 1'b0) || (INP.cxbenn[1] !== 1'b0) || (INP.cxbenn[2] !== 1'b0) || (INP.cxbenn[3] !== 1'b0)) &&
(INP.irdynn === 1'b0) && (INP.trdynn === 1'b0) && icommand === 15) ) begin
error_report(46); // All byte enables should be asserted during each data phase
end // if // of a Memory Write Invalidate cycle.
end // if
end
endtask // analyze;
task update_last;
begin
if ( INP.framenn !== 1'bx ) begin
last_frame = INP.framenn;
end // if
if ( INP.devselnn !== 1'bx ) begin
last_devsel = INP.devselnn;
end // if
if ( INP.irdynn !== 1'bx ) begin
last_irdy = INP.irdynn;
end // if
if ( INP.trdynn !== 1'bx ) begin
last_trdy = INP.trdynn;
end // if
if ( INP.stopnn !== 1'bx ) begin
last_stop = INP.stopnn;
end // if
if ( INP.locknn !== 1'bx ) begin
last_lock = INP.locknn;
end // if
if ( INP.sbonn !== 1'bx ) begin
last_sbo = INP.sbonn;
end // if
if ( INP.sdone !== 1'bx ) begin
last_sdone = INP.sdone;
end // if
if ( INP.perrnn !== 1'bx ) begin
last_perr = INP.perrnn;
end // if
if ( INP.serrnn !== 1'bx ) begin
last_serr = INP.serrnn;
end // if
if ( INP.req64nn !== 1'bx ) begin
last_req64 = INP.req64nn;
end // if
if ( INP.ack64nn !== 1'bx ) begin
last_ack64 = INP.ack64nn;
end // if
last_gnt = INP.gntnn;
last_req = INP.reqnn;
last_idsel = INP.idsel;
last_ad = address;
last_cbe = byte_en;
if (gnt_a_clks >= 1) begin
gnt_a_clks = gnt_a_clks + 1;
end
end
endtask // update_last;
task report_monitor;
begin
// issue initialization message
if ( model_flags.debug_level !== 0 ) begin
$fdisplay(fo,"= SYNOPSYS PCI MONITOR Model 5.0");
if ( trace_file ) begin
$fdisplay(fo,"= TRACE FILE = TRUE");
$fdisplay(fo,"= DATA_FILE = %s",data_file);
end else begin
$fdisplay(fo,"= TRACE FILE = FALSE");
end // if
if ( error_check ) begin
$fdisplay(fo,"= ERROR_CHECK = TRUE");
end else begin
$fdisplay(fo,"= ERROR_CHECK = FALSE");
end // if
if ( arbitrate ) begin
$fdisplay(fo,"= ARBITRATE = TRUE");
end else begin
$fdisplay(fo,"= ARBITRATE = FALSE");
end // if
if ( park_zero ) begin
$fdisplay(fo,"= PARK_ZERO = TRUE");
end else begin
$fdisplay(fo,"= PARK_ZERO = FALSE");
end // if
case ( priority )
0 : $fdisplay(fo,"= PRIORITY = FIXED (0) ");
1 : $fdisplay(fo,"= PRIORITY = ROTATING (1)");
2 : $fdisplay(fo,"= PRIORITY = REVERSING (2)");
3 : $fdisplay(fo,"= PRIORITY = MS15 TEST (3)");
4 : $fdisplay(fo,"= PRIORITY = FIXED MS16 TEST (4)");
default $fdisplay(fo,"= PRIORITY = FIXED (>4)");
endcase
end // if
end
endtask // report_monitor;
task update_flags;
input value;
begin
CNTRL.ad_in <= #(0) value;
CNTRL.cxbenn_in <= #(0) value;
CNTRL.par <= #(0) value;
CNTRL.framenn <= #(0) value;
CNTRL.trdynn <= #(0) value;
CNTRL.irdynn <= #(0) value;
CNTRL.stopnn <= #(0) value;
CNTRL.devselnn <= #(0) value;
CNTRL.idsel <= #(0) value;
CNTRL.perrnn <= #(0) value;
CNTRL.serrnn <= #(0) value;
CNTRL.reqnn <= #(0) value;
CNTRL.gntnn <= #(0) value;
CNTRL.r_locknn_clk <= #(0) value;
CNTRL.r_par64_clk <= #(0) value;
CNTRL.r_req64nn_clk <= #(0) value;
CNTRL.r_ack64nn_clk <= #(0) value;
CNTRL.r_sbonn_clk <= #(0) value;
CNTRL.r_sdone_clk <= #(0) value;
CNTRL.r_intann_clk <= #(0) value;
CNTRL.r_intbnn_clk <= #(0) value;
CNTRL.r_intcnn_clk <= #(0) value;
CNTRL.r_intdnn_clk <= #(0) value;
end
endtask
//-------------------------------
//-------------------------------
// User variable definitions --
// are to be entered here --
//-------------------------------
//-------------------------------
//--- FM MAIN PROCESS -----
always begin : fm_main
reg init_done;
integer left, right, left1, right1, i;
if ( init_done !== `true ) begin
CNTRL.clk <= #(0) `true;
CNTRL.ck_clk <= #(0) `true;
CNTRL.rstnn <= #(0) `true;
CNTRL.ck_rstnn <= #(0) `true;
CNTRL.ad_in <= #(0) `false;
CNTRL.r_ad_clk <= #(0) `false;
CNTRL.cxbenn_in <= #(0) `false;
CNTRL.r_cxbenn_clk <= #(0) `false;
CNTRL.par <= #(0) `false;
CNTRL.r_par_clk <= #(0) `false;
CNTRL.framenn <= #(0) `false;
CNTRL.r_framenn_clk <= #(0) `false;
CNTRL.trdynn <= #(0) `false;
CNTRL.r_trdynn_clk <= #(0) `false;
CNTRL.irdynn <= #(0) `false;
CNTRL.r_irdynn_clk <= #(0) `false;
CNTRL.stopnn <= #(0) `false;
CNTRL.r_stopnn_clk <= #(0) `false;
CNTRL.devselnn <= #(0) `false;
CNTRL.r_devselnn_clk <= #(0) `false;
CNTRL.idsel <= #(0) `false;
CNTRL.r_idsel_clk <= #(0) `false;
CNTRL.perrnn <= #(0) `false;
CNTRL.r_perrnn_clk <= #(0) `false;
CNTRL.serrnn <= #(0) `false;
CNTRL.r_serrnn_clk <= #(0) `false;
CNTRL.reqnn <= #(0) `false;
CNTRL.r_reqnn_clk <= #(0) `false;
CNTRL.gntnn <= #(0) `false;
CNTRL.gntnn_in <= #(0) `false;
CNTRL.r_gntnn_clk <= #(0) `false;
CNTRL.locknn <= #(0) `false;
CNTRL.r_locknn_clk <= #(0) `false;
CNTRL.par64 <= #(0) `false;
CNTRL.r_par64_clk <= #(0) `false;
CNTRL.req64nn <= #(0) `false;
CNTRL.r_req64nn_clk <= #(0) `false;
CNTRL.ack64nn <= #(0) `false;
CNTRL.r_ack64nn_clk <= #(0) `false;
CNTRL.sbonn <= #(0) `false;
CNTRL.r_sbonn_clk <= #(0) `false;
CNTRL.sdone <= #(0) `false;
CNTRL.r_sdone_clk <= #(0) `false;
CNTRL.intann <= #(0) `false;
CNTRL.r_intann_clk <= #(0) `false;
CNTRL.intbnn <= #(0) `false;
CNTRL.r_intbnn_clk <= #(0) `false;
CNTRL.intcnn <= #(0) `false;
CNTRL.r_intcnn_clk <= #(0) `false;
CNTRL.intdnn <= #(0) `false;
CNTRL.r_intdnn_clk <= #(0) `false;
init_done = `true;
//-------------------------------
//-------------------------------
// User initialization code is --
// to be entered here --
//-------------------------------
//-------------------------------
ad_out(64'hzzzzzzzzzzzzzzzz, zero_delay, 0 * `time_scale_multiplier);
cxbenn_out(8'bzzzzzzzz, zero_delay, 0 * `time_scale_multiplier);
par_out(1'bz, zero_delay, 0 * `time_scale_multiplier);
fo = $fopen(data_file);
if (model_flags.debug_level !== -1) begin
if (trace_file && disablemsg !== 1'b1) begin
trace_enable = `true;
end else begin
trace_enable = `false;
end // if
end else begin
trace_enable = `false;
end //if
end // if
//-------------------------------
//-------------------------------
// User model code goes here ----
//-------------------------------
//-------------------------------
if ( INP.rstnn_event ) begin
if ( INP.rstnn === 1'b0 ) begin
ad_out(64'hzzzzzzzzzzzzzzzz, zero_delay, 0 * `time_scale_multiplier);
cxbenn_out(8'bzzzzzzzz, zero_delay, 0 * `time_scale_multiplier);
par_out(1'bz, zero_delay, 0 * `time_scale_multiplier);
update_flags(`false);
end else if ( INP.rstnn === 1'b1 ) begin
update_flags(`true);
report_monitor;
end // if
end // if
if ( INP.clk_event && INP.clk === 1'b1 ) begin
if ( arbitrate ) begin
arbitrator;
end else begin
gntnn_out(8'bzzzzzzzz,model_times.tpr_clk_gntnn, 0 *`time_scale_multiplier);
end // if
monitor;
if ( INP.rstnn === 1'b1 ) begin
analyze;
end // if
check_timing;
update_last;
end // if
INP.clk_old = INP.clk;
INP.rstnn_old = INP.rstnn;
INP.ad_old = INP.ad;
INP.cxbenn_old = INP.cxbenn;
INP.par_old = INP.par;
INP.framenn_old = INP.framenn;
INP.trdynn_old = INP.trdynn;
INP.irdynn_old = INP.irdynn;
INP.stopnn_old = INP.stopnn;
This page: |
Created: | Thu Aug 19 12:00:10 1999 |
| From: |
../../../sparc_v8/system/lmc/rtl/pcimonitor_fm.v
|