endtask // cxbennl_out
task cxbennh_out;
input [7:4] output_vector;
input [127:0] delay_in;
input [31:0] skew_in;
integer delay[0:3];
integer delay_time, skew, i;
begin
delay[0] = delay_in[31:0];
delay[1] = delay_in[63:32];
delay[2] = delay_in[95:64];
delay[3] = delay_in[127:96];
skew = skew_in;
for (i=4; i<=7; i=i+1) begin
delay_time = delay[lmcver.map(output_vector[i])] + model_times.tld_cxbenn[i] + skew;
if (delay_time < 0) begin delay_time = 0; end
case (i)
4: cxbenn_reg_4 <= #( delay_time) output_vector[i];
5: cxbenn_reg_5 <= #( delay_time) output_vector[i];
6: cxbenn_reg_6 <= #( delay_time) output_vector[i];
7: cxbenn_reg_7 <= #( delay_time) output_vector[i];
endcase
end
end
endtask // cxbennh_out
task par_out;
input output_value;
input [127:0] delay_in;
input [31:0] skew_in;
integer delay[0:3];
integer delay_time, skew, i;
begin
delay[0] = delay_in[31:0];
delay[1] = delay_in[63:32];
delay[2] = delay_in[95:64];
delay[3] = delay_in[127:96];
skew = skew_in;
delay_time = delay[lmcver.map(output_value)] + model_times.tld_par + skew;
if (delay_time < 0) begin delay_time = 0; end
par_reg <= #( delay_time) output_value;
end
endtask // par_out
task gntnn_out;
input [7:0] output_vector;
input [127:0] delay_in;
input [31:0] skew_in;
integer delay[0:3];
integer delay_time, skew, i;
begin
delay[0] = delay_in[31:0];
delay[1] = delay_in[63:32];
delay[2] = delay_in[95:64];
delay[3] = delay_in[127:96];
skew = skew_in;
for (i=0; i<=7; i=i+1) begin
delay_time = delay[lmcver.map(output_vector[i])] + model_times.tld_gntnn[i] + skew;
if (delay_time < 0) begin delay_time = 0; end
case (i)
0: gntnn_reg_0 <= #( delay_time) output_vector[i];
1: gntnn_reg_1 <= #( delay_time) output_vector[i];
2: gntnn_reg_2 <= #( delay_time) output_vector[i];
3: gntnn_reg_3 <= #( delay_time) output_vector[i];
4: gntnn_reg_4 <= #( delay_time) output_vector[i];
5: gntnn_reg_5 <= #( delay_time) output_vector[i];
6: gntnn_reg_6 <= #( delay_time) output_vector[i];
7: gntnn_reg_7 <= #( delay_time) output_vector[i];
endcase
end
end
endtask // gntnn_out
function b;
input s;
reg result;
begin
result = 0;
case (s)
1'b1 : result = 1;
1'b0 : result = 0;
endcase
b = result;
end
endfunction
parameter zero_delay = {32'h0, 32'h0, 32'h0, 32'h0};
//type phases
parameter p_idle = 0;
parameter p_address = 1;
parameter p_tar = 2;
parameter p_data = 3;
//type bstate_type
parameter idle = 0;
parameter busy = 1;
//type lock_type
parameter owned = 0;
parameter free = 1;
//type command_type
parameter read = 0;
parameter write = 1;
//type burst_array is array(1 : 32) of integer;
//type cstr_array is array(0 : 15) of string(1 : 35);
//type astr_array is array(0 : 3) of string(1 : 24);
//type tstr_array is array(0 : 8) of string(1 : 17);
//type sstr_array is array(0 : 4) of string(1 : 14);
//type estr_array is array(1 : 50) of string(1 : 120);
integer current_phase
; initial current_phase
= p_idle;
integer last_phase
; initial last_phase
= p_idle;
integer abstate
; initial abstate
= idle;
integer lock_state
; initial lock_state
= free;
integer rw
; initial rw
= read;
reg relatch
; initial relatch
= `false;
reg daddress
; initial daddress
= `false;
reg cycle_start
; initial cycle_start
= `false;
reg cycle_end
; initial cycle_end
= `true;
reg last_transfer
; initial last_transfer
= `false;
reg ignore_cycle
; initial ignore_cycle
= `false;
reg cycle_locked
; initial cycle_locked
= `false;
reg fast_back2back
; initial fast_back2back
= `false;
reg data_phase_complete
; initial data_phase_complete
= `false;
reg memory_cmd
; initial memory_cmd
= `false;
reg irdy_asserted
; initial irdy_asserted
= `false;
reg trdy_asserted
; initial trdy_asserted
= `false;
reg devsel_asserted
; initial devsel_asserted
= `false;
reg stop_asserted
; initial stop_asserted
= `false;
reg parity_error
; initial parity_error
= `false;
integer speed
; initial speed
= 0;
integer termination
; initial termination
= 0;
integer master_req_size
; initial master_req_size
= 32;
integer slave_ack_size
; initial slave_ack_size
= 32;
integer frame_count
; initial frame_count
= 0;
integer cycle_count
; initial cycle_count
= 0;
integer devsel_count
; initial devsel_count
= 0;
integer irdy_count
; initial irdy_count
= 0;
integer trdy_count
; initial trdy_count
= 0;
integer irdy_wait
; initial irdy_wait
= 0;
integer trdy_wait
; initial trdy_wait
= 0;
integer stop_count
; initial stop_count
= 0;
integer transfer_count
; initial transfer_count
= 0;
integer icommand
; initial icommand
= 0;
integer iaddr10
; initial iaddr10
= 0;
integer cycle_status
; initial cycle_status
= 0;
integer gnt_cnt
; initial gnt_cnt
= 0;
integer file_gnt
; initial file_gnt
= 0;
integer irdy_burst
; initial irdy_burst
= 0;
integer trdy_burst
; initial trdy_burst
= 0;
reg [63:0] data_burst
;
reg [63:0] address
;
reg [7:0] byte_en
;
reg [3:0] command
;
reg last_frame
; initial last_frame
= 1'bx;
reg last_devsel
; initial last_devsel
= 1'bx;
reg last_irdy
; initial last_irdy
= 1'bx;
reg last_trdy
; initial last_trdy
= 1'bx;
reg last_stop
; initial last_stop
= 1'bx;
reg last_sdone
; initial last_sdone
= 1'bx;
reg last_sbo
; initial last_sbo
= 1'bx;
reg last_perr
; initial last_perr
= 1'bx;
reg last_serr
; initial last_serr
= 1'bx;
reg last_lock
; initial last_lock
= 1'bx;
reg last_req64
; initial last_req64
= 1'bx;
reg last_ack64
; initial last_ack64
= 1'bx;
reg parity
; initial parity
= 1'bx;
reg parity64
; initial parity64
= 1'bx;
reg [63:0] last_ad
;
reg [7:0] last_cbe
;
reg [7:0] last_idsel
;
reg [7:0] last_req
;
reg [7:0] last_gnt
;
integer fo
;
integer fp
;
reg trace_enable
; initial trace_enable
= `false;
reg first_reset
; initial first_reset
= `false;
integer master_data_latency
; initial master_data_latency
= 0;
reg master_latency_error
; initial master_latency_error
= `false;
integer slave_data_latency
; initial slave_data_latency
= 0;
reg slave_latency_error
; initial slave_latency_error
= `false;
integer current_ignt
; initial current_ignt
= 0;
integer gnt_a_clks
; initial gnt_a_clks
= 0;
/*
type cycle_data is record
command : integer;
address : std_logic_vector(31 downto 0);
gnt : integer;
retry : boolean;
end record;
type cycle_array is array(0 to 7) of cycle_data;
variable last_cycle : cycle_array;
*/
//type cycle_data [128:0] - ([128] retry, [127:96] gnt, [95:32] address, [31:0] command)
reg [128:0] last_cycle
[0:7];
reg [128:0] tmp_last_cycle
;
reg comment
; initial comment
= `true;
reg enabled
; initial enabled
= `false;
reg first
; initial first
= `false;
reg turn
; initial turn
= `false;
reg read_cycle
; initial read_cycle
= `false;
reg write_cycle
; initial write_cycle
= `false;
reg check_parity
; initial check_parity
= `false;
reg addr
; initial addr
= `false;
reg [1:120*8] error_str
[1:53];
initial begin
error_str[1] = "1 Only a single GNT# may be asserted on any clock (3.4) ";
error_str[2] = "2 AD2 must be 0 during the address phase of 64-bit transaction (3.10) ";
error_str[3] = "3 Only memory commands make sense when doing 64-bit transfers (3.10) ";
error_str[4] = "4 Stop must be deasserted the cycle immediately following FRAME being deasserted (3.3.3.2.1) ";
error_str[5] = "5 TRDY must be deasserted during Turnaround cycle on a read (3.3.1) ";
error_str[6] = "6 Target must issue DEVSEL before any other response (3.7.1) ";
error_str[7] = "7 FRAME cannot be deasserted before IRDY is asserted (3.3.3.1) ";
error_str[8] = "8 Illegal combination of AD1,AD0 and C/BE for I/O cycle. (3.2.2) ";
error_str[9] = "9 Targets must not respond to Reserved encodings (3.2.2) ";
error_str[10] = "10 Targets must not respond to the Special cycle (3.7.2) ";
error_str[11] = "11 Targets must not respond to configuration cycles unless selected (3.2.2) ";
error_str[12] = "12 Once FRAME is deasserted it cannot be reasserted during the same transaction (3.3.3.1) ";
error_str[13] = "13 Once a master has asserted IRDY# it cannot change FRAME# until the current data phase completes (3.2.1). ";
error_str[14] = "14 Once a master has asserted IRDY# it cannot change IRDY# until the current data phase completes (3.2.1). ";
error_str[15] = "15 Once a target has asserted TRDY# it cannot change TRDY# until the current data phase completes (3.2.1). ";
error_str[16] = "16 Once a target has asserted TRDY# it cannot change DEVSEL# until the current data phase completes (3.2.1). ";
error_str[17] = "17 Once a target has asserted TRDY# it cannot change STOP# until the current data phase completes (3.2.1). ";
error_str[18] = "18 DEVSEL must be asserted for 1 or more clocks before target-abort can be signaled (3.3.3.2) ";
error_str[19] = "19 TRDY must be deasserted before target-abort can be signaled (3.3.3.2.1) ";
error_str[20] = "20 Once a target has asserted STOP# it cannot change TRDY# until the current data phase completes (3.2.1). ";
error_str[21] = "21 Once a target has asserted STOP# it cannot change DEVSEL# until the current data phase completes (3.2.1). ";
error_str[22] = "22 Once a target has asserted STOP# it cannot change STOP# until the current data phase completes (3.2.1). ";
error_str[23] = "23 Once asserted, STOP# must remain asserted until FRAME# is deasserted (3.3.3.2.1). ";
error_str[24] = "24 IRDY# must always be asserted on the first clock edge that FRAME# is deasserted (3.3.3.1). ";
error_str[25] = "25 if DEVSEL is asserted, master abort termination is not permissible (3.3.3.1) ";
error_str[26] = "26 Once a target has asserted DEVSEL it must not be deaserted until the last data phase has completed (3.7.1) ";
error_str[27] = "27 The C/BE output buffers must remain enabled until the end of the transaction (3.3.1) ";
error_str[28] = "28 The C/BE must be valid during data phase (3.3.1) ";
error_str[29] = "29 The AD output buffers must remain enabled until the end of the transaction (3.3.1) ";
error_str[30] = "30 Dual Command (1101) not valid after dual command : cycle ignored (not in Spec) ";
error_str[31] = "31 Frame must remain asserted for cycle following dual command : cycle ignored (3.10.1) ";
error_str[32] = "32 Devsel asserted during address phase (3.7.1) ";
error_str[33] = "33 Devsel negated before cycle completion : ignored (3.7.1) ";
error_str[34] = "34 Devsel UNKNOWN during cycle: Ignored (3.7.1) ";
error_str[35] = "35 Parity must be driven within 1 PCI clock of C/BE and AD being driven (3.8.1) ";
error_str[36] = "36 C/BE and AD must be tristated within one PCI clock after GNT negation (3.4.3) ";
error_str[37] = "37 C/BE and AD must be driven within 8 PCI clocks of GNT assertion (3.4.3) ";
error_str[38] = "38 Parity Error Detected (3.8.1) ";
error_str[39] = "39 Cycle must not start unless GNT asserted (3.4.1) ";
error_str[40] = "40 One Clock delay required between GNTs during IDLE (3.4.1) ";
error_str[41] = "41 Master must deasserted REQ for a minimum of two PCI clocks , after target abort (3.3.3.2.2) ";
error_str[42] = "42 An agent must never use REQ to park itself on the bus (3.4.1) ";
error_str[43] = "43 Problem with current master, GNT asserted > 16 clocks with no access (3.4.1) ";
error_str[44] = "44 IRDY# must be asserted within eight clocks on all data phases (3.5.2) ";
error_str[45] = "45 Linear Burst Ordering must be used for Memory Write Invalidate cycles (3.2.1) ";
error_str[46] = "46 All byte enables should be asserted during each data phase of a Memory Write Invalidate cycle (3.2.1) ";
error_str[47] = "47 TRDY# should be asserted within 16 clocks of initial data phase(3.5.1.1) ";
error_str[48] = "48 Current cycle is not the same as previous cycle terminated by retry (WARNING)(3.3.3.2.2) ";
error_str[49] = "49 TRDY# must be deasserted the cycle immediately following the completion of the last data phase (3.3.3.2.1) ";
error_str[50] = "50 DEVSEL# must be deasserted the cycle immediately following the completion of the last data phase (3.3.3.2.1) ";
error_str[51] = "51 FRAME# must be deasserted whenever STOP# is asserted, as soon as IRDY# is asserted (3.3.3.2.1) (RULE 5) ";
error_str[52] = "52 Reserved ";
end
reg [1:35*8] cycle_str
[0:15];
initial begin
cycle_str[0] = "0 Interrupt Acknowledge ";
cycle_str[1] = "1 Special Cycle ";
cycle_str[2] = "2 I/O Read ";
cycle_str[3] = "3 I/O Write ";
cycle_str[4] = "4 Reserved ";
cycle_str[5] = "5 Reserved ";
cycle_str[6] = "6 Memory Read ";
cycle_str[7] = "7 Memory Write ";
cycle_str[8] = "8 Reserved ";
cycle_str[9] = "9 Reserved ";
cycle_str[10] = "A Configuration Read ";
cycle_str[11] = "B Configuration Write ";
cycle_str[12] = "C Memory Read Multiple ";
cycle_str[13] = "D Dual Address Cycle ";
cycle_str[14] = "E Memory Read Line ";
cycle_str[15] = "F Memory Write and Invalidate ";
end
reg [1:24*8] addr_str
[0:3];
initial begin
addr_str[0] = "0 Linear Incrementing ";
addr_str[1] = "1 Cache Line Toggle ";
addr_str[2] = "2 Cache Line Wrap ";
addr_str[3] = "3 Reserved mode ";
end
reg [1:19*8] term_str
[0:9];
initial begin
term_str[0] = "0 No Termination ";
term_str[1] = "1 Completion ";
term_str[2] = "2 Disconnect - A ";
term_str[3] = "3 Disconnect - B ";
term_str[4] = "4 Disconnect - C ";
term_str[5] = "5 Target - Abort ";
term_str[6] = "6 Master - Disc ";
term_str[7] = "7 Master - Abort ";
term_str[8] = "8 Master - Tout ";
term_str[9] = "9 Completion - MCT";
end
reg [1:14*8] speed_str
[0:4];
initial begin
speed_str[0] = "0 no_speed ";
speed_str[1] = "1 Fast ";
speed_str[2] = "2 Medium ";
speed_str[3] = "3 Slow ";
speed_str[4] = "4 Subtractive";
end
parameter linear_incrementing = 0;
parameter cache_line_toggle = 1;
parameter cache_line_wrap = 2;
parameter none = 0;
parameter na = 0;
parameter pass = 1;
parameter err = -1;
parameter interrupt_acknowledge = 0;
parameter special_cycle = 1;
parameter io_read = 2;
parameter io_write = 3;
parameter reserved_4 = 4;
parameter reserved_5 = 5;
parameter memory_read = 6;
parameter memory_write = 7;
parameter reserved_8 = 8;
parameter reserved_9 = 9;
parameter configuration_read = 10;
parameter configuration_write = 11;
parameter memory_read_multiple = 12;
parameter dual_address_cycle = 13;
parameter memory_read_line = 14;
parameter memory_write_invalidate = 15;
// The Column indexes
parameter gen = 0; // The Master Generates field
// Target speed
parameter no_speed = 0;
parameter fast_speed = 1;
parameter medium_speed = 2;
parameter slow_speed = 3;
parameter subtractive_speed = 4;
// Cycle Terminations
parameter no_termination = 0;
parameter completion = 1;
parameter disconnect_a = 2;
parameter disconnect_b = 3;
parameter disconnect_c = 4;
parameter target_abort = 5;
parameter master_disconnect = 6;
parameter master_abort = 7;
parameter master_timeout = 8;
parameter mct = 9;
integer i
,j
,k
;
initial begin
i = 0;
j = 0;
k = 0;
end
// inchar : character;
reg ok
;
parameter nobody = 99;
integer cur_gnt
; initial cur_gnt
= nobody;
integer highest_req
; initial highest_req
= nobody;
integer bus_owner
; initial bus_owner
= nobody;
integer lock_owner
; initial lock_owner
= nobody;
integer next_grant
; initial next_grant
= nobody;
reg negate_gnt
; initial negate_gnt
= `false;
parameter park_id = 0;
integer gclk
; initial gclk
= 0;
integer sclk
; initial sclk
= 0;
integer spclk
; initial spclk
= 0;
integer nptr
; initial nptr
= 3;
integer pcnt
; initial pcnt
= 0;
integer dcnt
; initial dcnt
= 0;
integer fcnt
; initial fcnt
= 0;
reg cpa
; initial cpa
= `false;
reg cpc
; initial cpc
= `false;
integer park_cnt
; initial park_cnt
= 0;
reg parking
; initial parking
= `false;
function is_z_cxbenn;
input [3:0] vec;
reg cond;
begin
cond = `true;
begin: loop3
for (i = 3; i >= 0; i = i - 1) begin
if (vec[i] !== 1'bz) begin
cond = `false;
disable loop3;
end // if
end // loop
end
is_z_cxbenn = cond;
end
endfunction // is_z_cxbenn
function is_z_ad;
input [31:0] vec;
reg cond;
begin
cond = `true;
begin: loop4
for (i = 31; i >= 0; i = i - 1) begin
if (vec[i] !== 1'bz) begin
cond = `false;
disable loop4;
end // if
end // loop
end
is_z_ad = cond;
end
endfunction // is_z_ad
task error_report;
input [31:0] number;
integer temp;
begin
if ( error_check !== 0 ) begin
if (disablemsg !== 1'b1) begin
$fdisplay(fo,"PCI ERROR : %s",error_str[number]);
end
if (!(`false)) begin
$display("WARNING at %0t from %m",$time);
$write(" \"PCI ERROR : %s",error_str[number]);
$display("\"");
end
end // if
end
endtask // error_report
task assert_gnt;
input [31:0] r;
begin
case (r)
0 : begin
gntnn_out(8'b11111110,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 0;
end
1 : begin
gntnn_out(8'b11111101,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 1;
end
2 : begin
gntnn_out(8'b11111011,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 2;
end
3 : begin
gntnn_out(8'b11110111,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 3;
end
4 : begin
gntnn_out(8'b11101111,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 4;
end
5 : begin
gntnn_out(8'b11011111,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 5;
end
6 : begin
gntnn_out(8'b10111111,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 6;
end
7 : begin
gntnn_out(8'b01111111,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = 7;
end
nobody : begin
gntnn_out(8'b11111111,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
cur_gnt = nobody;
end
default begin
if (!(`false)) begin
$display("WARNING at %0t from %m",$time);
$write(" \"Trying to assert an invalid index in assert_gnt.");
$display("\"");
end
end
endcase
if (cur_gnt === 2) begin
gnt_a_clks = 1;
end
end
endtask // assert_gnt
task check_timing;
begin
// Control setup and hold checks
if ( INP.rstnn === 1'b0 ) begin
CNTRL.r_reqnn_clk <= #(0) `false;
CNTRL.r_gntnn_clk <= #(0) `false;
CNTRL.r_intann_clk <= #(0) `false;
CNTRL.r_intbnn_clk <= #(0) `false;
CNTRL.r_intcnn_clk <= #(0) `false;
CNTRL.r_intdnn_clk <= #(0) `false;
CNTRL.r_serrnn_clk <= #(0) `false;
end else if ( INP.rstnn === 1'b1 ) begin
CNTRL.r_reqnn_clk <= #(0) `true;
CNTRL.r_gntnn_clk <= #(0) `true;
// CNTRL.r_intann_clk <= TRUE;
// CNTRL.r_intbnn_clk <= TRUE;
// CNTRL.r_intcnn_clk <= TRUE;
// CNTRL.r_intdnn_clk <= TRUE;
end // if
if ( current_phase === p_address ) begin
enabled = `true;
addr = `true;
CNTRL.r_ad_clk <= #(0) `true;
CNTRL.r_cxbenn_clk <= #(0) `true;
CNTRL.r_req64nn_clk <= #(0) `true;
CNTRL.r_framenn_clk <= #(0) `true;
CNTRL.r_trdynn_clk <= #(0) `false;
CNTRL.r_irdynn_clk <= #(0) `false;
CNTRL.r_stopnn_clk <= #(0) `false;
CNTRL.r_devselnn_clk <= #(0) `false;
CNTRL.r_idsel_clk <= #(0) `true;
CNTRL.r_locknn_clk <= #(0) `false;
CNTRL.r_ack64nn_clk <= #(0) `false;
if ( (fast_back2back) ) begin
CNTRL.r_par_clk <= #(0) `true;
end else begin
CNTRL.r_par_clk = `false;
end // if
end // if
if ( (enabled) ) begin
if ( current_phase === p_tar ) begin
turn = `true;
CNTRL.r_ad_clk <= #(0) `false;
CNTRL.r_cxbenn_clk <= #(0) `true;
if ( (INP.ack64nn === 1'b0) ) begin
CNTRL.cxbenn_in <= #(0) `true;
end // if
CNTRL.ad_in <= #(0) `false;
CNTRL.r_cxbenn_clk <= #(0) `true;
CNTRL.r_par_clk <= #(0) `true;
CNTRL.r_framenn_clk <= #(0) `false;
CNTRL.r_trdynn_clk <= #(0) `false;
CNTRL.r_irdynn_clk <= #(0) `true;
CNTRL.r_stopnn_clk <= #(0) `false;
CNTRL.r_devselnn_clk <= #(0) `false;
CNTRL.r_idsel_clk <= #(0) `false;
CNTRL.r_perrnn_clk <= #(0) `false;
CNTRL.r_serrnn_clk <= #(0) `false;
CNTRL.r_locknn_clk <= #(0) `false;
CNTRL.r_par64_clk <= #(0) `false;
CNTRL.r_req64nn_clk <= #(0) `false;
CNTRL.r_ack64nn_clk <= #(0) `false;
CNTRL.r_sbonn_clk <= #(0) `false;
CNTRL.r_sdone_clk <= #(0) `false;
end else if ( (current_phase === p_data) ) begin
if ( (INP.irdynn === 1'b0 && INP.trdynn === 1'b0) ) begin
CNTRL.r_ad_clk <= #(0) `true;
if ( (INP.ack64nn === 1'b0) ) begin
CNTRL.ad_in <= #(0) `true;
end // if
end else begin
CNTRL.r_ad_clk <= #(0) `false;
CNTRL.ad_in <= #(0) `false;
end // if
if (!disconnect_c) begin
CNTRL.r_cxbenn_clk <= #(0) `true;
end else begin
CNTRL.r_cxbenn_clk <= #(0) `false;
end
if ( INP.ack64nn === 1'b0 ) begin
CNTRL.cxbenn_in <= #(0) `true;
end // if
if ( turn ) begin
turn = `false;
addr = `false;
CNTRL.r_par_clk <= #(0) `false;
CNTRL.r_par64_clk <= #(0) `false;
CNTRL.r_perrnn_clk <= #(0) `false;
end else begin
CNTRL.r_par_clk <= #(0) `true;
if ( (INP.ack64nn === 1'b0) ) begin
CNTRL.r_par64_clk <= #(0) `true;
end // if
if ( addr ) begin
addr = `false;
CNTRL.r_perrnn_clk <= #(0) `false;
end else begin
if ( (perrnn !== 1'b1 /* 'H' */ && perrnn !== 1'bz) ) begin
CNTRL.r_perrnn_clk <= #(0) `true;
end // if
end // if
end // if
CNTRL.r_framenn_clk <= #(0) `true;
if ( (fast_back2back) ) begin
CNTRL.r_trdynn_clk <= #(0) `false;
CNTRL.r_stopnn_clk <= #(0) `false;
CNTRL.r_devselnn_clk <= #(0) `false;
CNTRL.r_ack64nn_clk <= #(0) `false;
end else begin
CNTRL.r_trdynn_clk <= #(0) `true;
CNTRL.r_stopnn_clk <= #(0) `true;
CNTRL.r_devselnn_clk <= #(0) `true;
CNTRL.r_ack64nn_clk <= #(0) `true;
end // if
CNTRL.r_irdynn_clk <= #(0) `true;
CNTRL.r_idsel_clk <= #(0) `false;
CNTRL.r_locknn_clk <= #(0) `true;
CNTRL.r_req64nn_clk <= #(0) `true;
CNTRL.r_sbonn_clk <= #(0) `true;
CNTRL.r_sdone_clk <= #(0) `true;
if ( current_phase === p_idle ) begin // was next_Phase
enabled = `false;
end // if
end // if
end else begin
CNTRL.r_ad_clk <= #(0) `false;
CNTRL.r_cxbenn_clk <= #(0) `false;
CNTRL.ad_in <= #(0) `false;
CNTRL.cxbenn_in <= #(0) `false;
CNTRL.r_par_clk <= #(0) `false;
CNTRL.r_framenn_clk <= #(0) `false;
CNTRL.r_trdynn_clk <= #(0) `false;
CNTRL.r_irdynn_clk <= #(0) `false;
CNTRL.r_stopnn_clk <= #(0) `false;
CNTRL.r_devselnn_clk <= #(0) `false;
CNTRL.r_idsel_clk <= #(0) `false;
CNTRL.r_perrnn_clk <= #(0) `false;
CNTRL.r_serrnn_clk <= #(0) `false;
CNTRL.r_locknn_clk <= #(0) `false;
CNTRL.r_par64_clk <= #(0) `false;
CNTRL.r_req64nn_clk <= #(0) `false;
CNTRL.r_ack64nn_clk <= #(0) `false;
CNTRL.r_sbonn_clk <= #(0) `false;
CNTRL.r_sdone_clk <= #(0) `false;
end // if
end
endtask // check_timing;
task arbitrator;
begin
if ( (INP.rstnn === 1'b1) ) begin
CNTRL.r_reqnn_clk <= #(0) `true;
//--------------------------------------------------------------------------
//
// this code determines priorities. replace this code to get
// different schemes. one 'signal' is generated from here.
// 'highest_req' should contain the number of a request that is
// highest priority. if nobody is requesting the bus, then its
// value should be 'nobody'.
//--------------------------------------------------------------------------
case ( priority )
0 , 4 : begin // FIXED priority REQ(0) is highest
if ( INP.reqnn[0] === 1'b0 ) begin
highest_req = 0;
end else if ( INP.reqnn[1] === 1'b0 ) begin
highest_req = 1;
end else if ( INP.reqnn[2] === 1'b0 ) begin
highest_req = 2;
end else if ( INP.reqnn[3] === 1'b0 ) begin
highest_req = 3;
end else if ( INP.reqnn[4] === 1'b0 ) begin
highest_req = 4;
end else if ( INP.reqnn[5] === 1'b0 ) begin
highest_req = 5;
end else if ( INP.reqnn[6] === 1'b0 ) begin
highest_req = 6;
end else if ( INP.reqnn[7] === 1'b0 ) begin
highest_req = 7;
end else begin
highest_req = nobody;
end // if
end
1 : begin // Rotating
// if ( INP.reqnn !== last_req && &(INP.reqnn) === 1'b0 ) begin
// nptr = (nptr + 1) % 8;
if ( INP.reqnn[nptr] === 1'b0 ) begin
highest_req = nptr;
end else if ( INP.reqnn[(nptr + 1) % 8] === 1'b0 ) begin
highest_req = (nptr + 1) % 8;
end else if ( INP.reqnn[(nptr + 2) % 8] === 1'b0 ) begin
highest_req = (nptr + 2) % 8;
end else if ( INP.reqnn[(nptr + 3) % 8] === 1'b0 ) begin
highest_req = (nptr + 3) % 8;
end else if ( INP.reqnn[(nptr + 4) % 8] === 1'b0 ) begin
highest_req = (nptr + 4) % 8;
end else if ( INP.reqnn[(nptr + 5) % 8] === 1'b0 ) begin
highest_req = (nptr + 5) % 8;
end else if ( INP.reqnn[(nptr + 6) % 8] === 1'b0 ) begin
highest_req = (nptr + 6) % 8;
end else if ( INP.reqnn[(nptr + 7) % 8] === 1'b0 ) begin
highest_req = (nptr + 7) % 8;
end else begin
highest_req = nobody;
end // if
if ((INP.framenn === 1'b0) && (last_frame === 1'b1)) begin
nptr = (highest_req + 1) % 8;
end // if
// end // if
end
2 : begin // Reversing
if ( INP.reqnn !== last_req && &(INP.reqnn) === 1'b0 ) begin
if ( nptr === 0 ) begin
nptr = 7;
if ( INP.reqnn[0] === 1'b0 ) begin
highest_req = 0;
end else if ( INP.reqnn[1] === 1'b0 ) begin
highest_req = 1;
end else if ( INP.reqnn[2] === 1'b0 ) begin
highest_req = 2;
end else if ( INP.reqnn[3] === 1'b0 ) begin
highest_req = 3;
end else if ( INP.reqnn[4] === 1'b0 ) begin
highest_req = 4;
end else if ( INP.reqnn[5] === 1'b0 ) begin
highest_req = 5;
end else if ( INP.reqnn[6] === 1'b0 ) begin
highest_req = 6;
end else if ( INP.reqnn[7] === 1'b0 ) begin
highest_req = 7;
end else begin
highest_req = nobody;
end // if
end else begin
nptr = 0;
if ( INP.reqnn[7] === 1'b0 ) begin
highest_req = 0;
end else if ( INP.reqnn[6] === 1'b0 ) begin
highest_req = 1;
end else if ( INP.reqnn[5] === 1'b0 ) begin
highest_req = 2;
end else if ( INP.reqnn[4] === 1'b0 ) begin
highest_req = 3;
end else if ( INP.reqnn[3] === 1'b0 ) begin
highest_req = 4;
end else if ( INP.reqnn[2] === 1'b0 ) begin
highest_req = 5;
end else if ( INP.reqnn[1] === 1'b0 ) begin
highest_req = 6;
end else if ( INP.reqnn[0] === 1'b0 ) begin
highest_req = 7;
end else begin
highest_req = nobody;
end // if
end // if
end // if
end
3 : begin // FIXED for Master Scenario 1.15 (parking)
pcnt = pcnt + 1;
if ( pcnt < 10 ) begin
highest_req = nobody;
end else if ( pcnt < 20 ) begin
highest_req = 2;
end else begin
highest_req = nobody;
pcnt = 0;
end // if
end
default begin // Default to FIXED
if ( INP.reqnn[0] === 1'b0 ) begin
highest_req = 0;
end else if ( INP.reqnn[1] === 1'b0 ) begin
highest_req = 1;
end else if ( INP.reqnn[2] === 1'b0 ) begin
highest_req = 2;
end else if ( INP.reqnn[3] === 1'b0 ) begin
highest_req = 3;
end else if ( INP.reqnn[4] === 1'b0 ) begin
highest_req = 4;
end else if ( INP.reqnn[5] === 1'b0 ) begin
highest_req = 5;
end else if ( INP.reqnn[6] === 1'b0 ) begin
highest_req = 6;
end else if ( INP.reqnn[7] === 1'b0 ) begin
highest_req = 7;
end else begin
highest_req = nobody;
end // if
end
endcase
//--------------------------------------------------------------------------
//
// now do something special to handle lock conditions on the bus.
// arbitration rules say that once someone has asserted lock, that
// device has to be guaranteed access to the bus again (effectively
// made highest priority). the statements below, make the bus locker
// the highest priority.
//
//--------------------------------------------------------------------------
case ( lock_owner )
0 : begin
if ( INP.reqnn[0] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
1 : begin
if ( INP.reqnn[1] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
2 : begin
if ( INP.reqnn[2] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
3 : begin
if ( INP.reqnn[3] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
4 : begin
if ( INP.reqnn[4] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
5 : begin
if ( INP.reqnn[5] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
6 : begin
if ( INP.reqnn[6] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
7 : begin
if ( INP.reqnn[7] === 1'b0 ) begin
highest_req = lock_owner;
end // if
end
default begin
/* null */
end
endcase
//--------------------------------------------------------------------------
//
// this machine
// this machine determines the state of the bus.
//
//--------------------------------------------------------------------------
if ( b(INP.framenn) && b(INP.irdynn) ) begin
abstate = idle;
bus_owner = cur_gnt;
if ( (priority === 4 && INP.reqnn[2] === 1'b0) && (gnt_a_clks >=
`GNT_ASSERTED_CLKS + 1) ) begin
negate_gnt = `true;
gnt_a_clks = 0;
end // if
end else begin
if ((!b(INP.framenn) && priority === 4 && INP.reqnn[2] === 1'b0) &&
(gnt_a_clks >=`GNT_ASSERTED_CLKS + 1) ) begin
negate_gnt = `true;
gnt_a_clks = 0;
end
abstate = busy;
end // if
//--------------------------------------------------------------------------
//
// this machine determines who owns the lock line. this is needed
// so that the guy who owns the lock is guaranteed to get access to
// the bus.
//
//--------------------------------------------------------------------------
case ( lock_state )
free : begin
if ( ! b(INP.locknn) ) begin
lock_state = owned;
lock_owner = bus_owner;
end // if
end
owned : begin
if ( b(INP.framenn) && b(INP.locknn) ) begin
lock_owner = nobody;
lock_state = free;
end // if
end
endcase
//--------------------------------------------------------------------------
//
// this machine determines when gnt lines can be driven.
//
//--------------------------------------------------------------------------
if ( cur_gnt === nobody ) begin // no gnt driven
negate_gnt = `false;
if ( highest_req === nobody ) begin // no reqs asserted
if ( (park_zero) ) begin
assert_gnt(park_id);
end else begin
assert_gnt(nobody);
end // if
end else begin
assert_gnt(highest_req);
end // if
end else begin
if ( highest_req === nobody ) begin // no reqs asserted
negate_gnt = `false;
if ( abstate === busy || cur_gnt === park_id ) begin
if ( (park_zero) ) begin
assert_gnt(park_id);
end else begin
assert_gnt(nobody);
end // if
end else begin
assert_gnt(nobody);
end // if
end else if ( highest_req !== cur_gnt ) begin // need to switch gnts
negate_gnt = `false;
if ( abstate === busy ) begin
assert_gnt(highest_req);
end else begin
assert_gnt(nobody);
end // if
end else begin // same guy
if ( negate_gnt ) begin
assert_gnt(nobody);
// gntnn_out(8'b11111111,model_times.tpr_clk_gntnn,0 *`time_scale_multiplier);
// cur_gnt = nobody;
end // if
end // if
end // if
if ( ! park_zero ) begin
if ( highest_req === nobody && cur_gnt === nobody && abstate === idle ) begin
fcnt = 0;
dcnt = (dcnt + 1) % 5;
if ( dcnt === 3 ) begin
adl_out(32'h5A5A5A5A, zero_delay, 5*`time_scale_multiplier);
cxbennl_out(4'b0101, zero_delay, 5*`time_scale_multiplier);
end // if
if ( dcnt === 4 ) begin
par_out(1'b0, zero_delay, 5*`time_scale_multiplier);
end // if
end else begin
dcnt = 0;
fcnt = (fcnt + 1) % 3;
adl_out(32'bzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, zero_delay, 5*`time_scale_multiplier);
cxbennl_out(4'bzzzz, zero_delay, 5*`time_scale_multiplier);
if ( (fcnt === 2) ) begin
par_out(1'bz, zero_delay, 5*`time_scale_multiplier);
end // if
end // if
end // if
end else begin
negate_gnt = `false;
assert_gnt(nobody);
CNTRL.r_reqnn_clk <= #(0) `false;
end // if
end
endtask // arbitrator;
task monitor;
integer temp;
reg tmp;
This page: |
Created: | Thu Aug 19 12:00:07 1999 |
| From: |
../../../sparc_v8/system/lmc/rtl/pcimonitor_fm.v
|