Line 13... |
Line 13... |
TRDY,
|
TRDY,
|
STOP,
|
STOP,
|
PAR
|
PAR
|
);
|
);
|
|
|
|
parameter normal = 0 ;
|
|
parameter disconnect = 1 ;
|
|
parameter retry = 2 ;
|
|
parameter target_abort = 3 ;
|
|
parameter master_abort = 4 ;
|
|
parameter error = 5 ;
|
|
|
input CLK ;
|
input CLK ;
|
output [31:0] AD ;
|
inout [31:0] AD ;
|
output [3:0] CBE ;
|
inout [3:0] CBE ;
|
input RST ;
|
input RST ;
|
output REQ ;
|
output REQ ;
|
input GNT ;
|
input GNT ;
|
output FRAME ;
|
inout FRAME ;
|
output IRDY ;
|
inout IRDY ;
|
input DEVSEL ;
|
input DEVSEL ;
|
input TRDY ;
|
input TRDY ;
|
input STOP ;
|
input STOP ;
|
output PAR ;
|
inout PAR ;
|
|
|
|
reg [31:0] AD_int ;
|
|
reg AD_en ;
|
|
|
|
reg [3:0] CBE_int ;
|
|
reg CBE_en ;
|
|
|
|
reg FRAME_int ;
|
|
reg FRAME_en ;
|
|
|
|
reg IRDY_int ;
|
|
reg IRDY_en ;
|
|
|
|
reg PAR_int ;
|
|
reg PAR_en ;
|
|
|
|
assign AD = AD_en ? AD_int : 32'hzzzz_zzzz ;
|
|
assign CBE = CBE_en ? CBE_int : 4'hz ;
|
|
assign FRAME = FRAME_en ? FRAME_int : 1'bz ;
|
|
assign IRDY = IRDY_en ? IRDY_int : 1'bz ;
|
|
assign PAR = PAR_en ? PAR_int : 1'bz ;
|
|
|
reg [31:0] AD ;
|
|
reg [3:0] CBE ;
|
|
reg REQ ;
|
reg REQ ;
|
reg FRAME ;
|
|
reg IRDY ;
|
event e_finish_transaction ;
|
reg PAR ;
|
event e_transfers_done ;
|
|
|
|
reg write ;
|
|
reg make_parity_error_after_last_dataphase ;
|
|
|
initial
|
initial
|
begin
|
begin
|
REQ = 1'b1 ;
|
REQ = 1'b1 ;
|
AD = 32'hzzzz_zzzz ;
|
AD_en = 1'b0 ;
|
CBE = 4'bzzzz ;
|
CBE_en = 1'b0 ;
|
FRAME = 1'bz ;
|
FRAME_en = 1'b0 ;
|
IRDY = 1'bz ;
|
IRDY_en = 1'b0 ;
|
PAR = 1'bz ;
|
PAR_en = 1'b0 ;
|
|
write = 1'b0 ;
|
|
make_parity_error_after_last_dataphase = 1'b0 ;
|
end
|
end
|
|
|
task master_reference ;
|
task unsupported_reference ;
|
input [31:0] addr1 ;
|
input [31:0] addr1 ;
|
input [31:0] addr2 ;
|
input [31:0] addr2 ;
|
input [3:0] bc1 ;
|
input [3:0] bc1 ;
|
input [3:0] bc2 ;
|
input [3:0] bc2 ;
|
input [3:0] be ;
|
input [3:0] be ;
|
Line 55... |
Line 86... |
input make_addr_perr1 ;
|
input make_addr_perr1 ;
|
input make_addr_perr2 ;
|
input make_addr_perr2 ;
|
output ok ;
|
output ok ;
|
integer i ;
|
integer i ;
|
reg dual_address ;
|
reg dual_address ;
|
begin
|
reg [2:0] received_termination ;
|
|
begin:main
|
ok = 1 ;
|
ok = 1 ;
|
dual_address = (bc1 == `BC_DUAL_ADDR_CYC) ;
|
dual_address = (bc1 == `BC_DUAL_ADDR_CYC) ;
|
@(posedge CLK) ;
|
|
while( GNT == 1 )
|
get_bus_ownership(ok) ;
|
|
if (ok !== 1'b1)
|
|
disable main ;
|
|
|
|
addr_phase1(addr1, bc1) ;
|
|
|
|
if ( dual_address )
|
begin
|
begin
|
REQ <= #1 1'b0 ;
|
write = bc2[0] ;
|
@(posedge CLK) ;
|
addr_phase2(addr2, bc2, make_addr_perr1) ;
|
|
first_and_last_data_phase(bc2[0], data, be, make_addr_perr2, 1'b0, received_termination) ;
|
|
finish_transaction(bc2[0], 1'b0) ;
|
|
end
|
|
else
|
|
begin
|
|
write = bc1[0] ;
|
|
first_and_last_data_phase(bc1[0], data, be, make_addr_perr1, 1'b0, received_termination) ;
|
|
finish_transaction(bc1[0], 1'b0) ;
|
end
|
end
|
|
|
REQ <= #1 1'b1 ;
|
if (received_termination !== master_abort)
|
FRAME <= #1 1'b0 ;
|
begin
|
AD <= #1 addr1 ;
|
ok = 0 ;
|
CBE <= #1 bc1 ;
|
end
|
|
end
|
|
endtask // master_reference
|
|
|
// end of first address cycle
|
// task added for target overflow testing
|
@(posedge CLK) ;
|
// master writes the addresses to the coresponding locations
|
PAR <= #1 ^{AD, CBE, make_addr_perr1} ;
|
task normal_write_transfer ;
|
if ( dual_address )
|
input [31:0] start_address ;
|
|
input [3:0] bus_command ;
|
|
input [31:0] size ;
|
|
input [2:0] wait_cycles ;
|
|
output [31:0] actual_transfer ;
|
|
output [2:0] received_termination ;
|
|
reg ok ;
|
|
reg [31:0] current_address ;
|
|
begin:main
|
|
|
|
write = 1'b1 ;
|
|
get_bus_ownership (ok) ;
|
|
if (ok !== 1'b1)
|
begin
|
begin
|
IRDY <= #1 1'b1 ;
|
received_termination = error ;
|
AD <= #1 addr2 ;
|
disable main ;
|
CBE <= #1 bc2 ;
|
end
|
|
|
|
make_parity_error_after_last_dataphase = 1'b0 ;
|
|
|
|
addr_phase1(start_address, bus_command) ;
|
|
actual_transfer = 0 ;
|
|
if (size == 1)
|
|
begin
|
|
first_and_last_data_phase (1'b1, ~start_address, 4'hF, 1'b0, 1'b0, received_termination) ;
|
|
if ((received_termination == normal) || (received_termination == disconnect))
|
|
actual_transfer = 1 ;
|
|
|
|
-> e_finish_transaction ;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
IRDY <= #1 1'b0 ;
|
current_address = start_address ;
|
FRAME <= #1 1'b1 ;
|
first_data_phase (1'b1, ~start_address, 4'hF, 1'b0, 1'b0, received_termination) ;
|
CBE <= #1 be ;
|
if ((received_termination == normal) || (received_termination == disconnect))
|
if ( bc1[0] )
|
actual_transfer = 1 ;
|
AD <= #1 data ;
|
|
|
if (received_termination == master_abort)
|
|
begin
|
|
-> e_transfers_done ;
|
|
end
|
|
|
|
while ((actual_transfer < (size - 1)) && (received_termination == normal))
|
|
begin
|
|
current_address = current_address + 4 ;
|
|
insert_waits(1'b1, wait_cycles, received_termination) ;
|
|
if (received_termination === normal)
|
|
begin
|
|
subsequent_data_phase(1'b1, ~current_address, 4'hF, 1'b0, received_termination) ;
|
|
if ((received_termination == normal) || (received_termination == disconnect))
|
|
actual_transfer = actual_transfer + 1 ;
|
|
end
|
|
end
|
|
|
|
if (received_termination == normal)
|
|
begin
|
|
insert_waits(1'b1, wait_cycles, received_termination) ;
|
|
if (received_termination === normal)
|
|
begin
|
|
last_data_phase(1'b1, ~current_address, 4'hF, 1'b0, received_termination) ;
|
|
if ((received_termination == normal) || (received_termination == disconnect))
|
|
actual_transfer = actual_transfer + 1 ;
|
|
|
|
-> e_finish_transaction ;
|
|
end
|
|
else
|
|
-> e_transfers_done ;
|
|
end
|
else
|
else
|
AD <= #1 32'hzzzz_zzzz ;
|
-> e_transfers_done ;
|
|
end
|
end
|
end
|
|
endtask // normal_write_transfer
|
|
|
|
task get_bus_ownership ;
|
|
output ok ;
|
|
integer deadlock ;
|
|
begin
|
|
deadlock = 0 ;
|
@(posedge CLK) ;
|
@(posedge CLK) ;
|
CBE <= #1 be ;
|
while( ((GNT !== 0) || (FRAME !== 1'b1) || (IRDY !== 1'b1)) && (deadlock < 5000) )
|
if ( dual_address )
|
begin
|
|
REQ <= #6 1'b0 ;
|
|
@(posedge CLK) ;
|
|
deadlock = deadlock + 1 ;
|
|
end
|
|
|
|
if (GNT !== 0)
|
begin
|
begin
|
PAR <= #1 ^{AD, CBE, make_addr_perr2} ;
|
$display("*E, PCI Master could not get ownership of the bus in 5000 cycles") ;
|
IRDY <= #1 1'b0 ;
|
ok = 0 ;
|
FRAME <= #1 1'b1 ;
|
end
|
if ( bc2[0] )
|
|
AD <= #1 data ;
|
|
else
|
else
|
AD <= #1 32'hzzzz_zzzz ;
|
begin
|
|
ok = 1 ;
|
|
end
|
|
|
|
REQ <= #6 1'b1 ;
|
end
|
end
|
|
endtask // get_bus_ownership
|
|
|
|
task addr_phase1 ;
|
|
input [31:0] address ;
|
|
input [3:0] bus_command ;
|
|
begin
|
|
FRAME_en <= #6 1'b1 ;
|
|
FRAME_int <= #6 1'b0 ;
|
|
|
|
AD_en <= #6 1'b1 ;
|
|
AD_int <= #6 address ;
|
|
|
|
CBE_en <= #6 1'b1 ;
|
|
CBE_int <= #6 bus_command ;
|
|
@(posedge CLK) ;
|
|
end
|
|
endtask // addr_phase1
|
|
|
|
task addr_phase2 ;
|
|
input [31:0] address ;
|
|
input [3:0] bus_command ;
|
|
input make_parity_error;
|
|
begin
|
|
PAR_int <= #6 ^{AD, CBE, make_parity_error} ;
|
|
PAR_en <= #6 1'b1 ;
|
|
AD_int <= #6 address ;
|
|
CBE_int <= #6 bus_command ;
|
|
@(posedge CLK) ;
|
|
end
|
|
endtask
|
|
|
|
task first_and_last_data_phase ;
|
|
input rw ;
|
|
input [31:0] data ;
|
|
input [3:0] be ;
|
|
input make_addr_parity_error ;
|
|
input make_data_parity_error ;
|
|
output [2:0] received_termination ;
|
|
integer i ;
|
|
begin
|
|
FRAME_int <= #6 1'b1 ;
|
|
first_data_phase (rw, data, be, make_addr_parity_error, make_data_parity_error, received_termination) ;
|
|
end
|
|
endtask // first_and_last_data_phase
|
|
|
|
task first_data_phase ;
|
|
input rw ;
|
|
input [31:0] data ;
|
|
input [3:0] be ;
|
|
input make_addr_parity_error ;
|
|
input make_data_parity_error ;
|
|
output [2:0] received_termination ;
|
|
integer i ;
|
|
begin
|
|
PAR_int <= #6 ^{AD, CBE, make_addr_parity_error} ;
|
|
PAR_en <= #6 1'b1 ;
|
|
IRDY_en <= #6 1'b1 ;
|
|
IRDY_int <= #6 1'b0 ;
|
|
CBE_int <= #6 be ;
|
|
if (rw)
|
|
AD_int <= #6 data ;
|
else
|
else
|
|
AD_en <= #6 1'b0 ;
|
|
|
|
@(posedge CLK) ;
|
|
if (!rw)
|
|
PAR_en <= #6 1'b0 ;
|
|
else
|
|
PAR_int <= #6 ^{AD, CBE, make_data_parity_error} ;
|
|
|
|
i = 1 ;
|
|
while ( (i < 5) && (DEVSEL === 1'b1) )
|
|
begin
|
|
@(posedge CLK) ;
|
|
i = i + 1 ;
|
|
end
|
|
|
|
if (DEVSEL === 1'b1)
|
begin
|
begin
|
if ( bc1[0] )
|
received_termination = master_abort ;
|
PAR <= #1 ^{AD, CBE} ;
|
end
|
else
|
else
|
PAR <= #1 1'bz ;
|
begin
|
|
get_termination(received_termination);
|
|
end
|
|
end
|
|
endtask // first_data_phase
|
|
|
|
task subsequent_data_phase ;
|
|
input rw ;
|
|
input [31:0] data ;
|
|
input [3:0] be ;
|
|
input make_parity_error ;
|
|
output [2:0] received_termination ;
|
|
begin
|
|
if (rw)
|
|
begin
|
|
PAR_int <= #6 ^{AD, CBE, make_parity_error} ;
|
|
AD_int <= #6 data ;
|
end
|
end
|
|
|
|
IRDY_int <= #6 1'b0 ;
|
|
CBE_int <= #6 be ;
|
@(posedge CLK) ;
|
@(posedge CLK) ;
|
if ( AD[31] !== 1'bz )
|
get_termination(received_termination);
|
PAR <= #1 ^{AD, CBE} ;
|
end
|
|
endtask // subsequent_data_phase
|
|
|
|
task last_data_phase ;
|
|
input rw ;
|
|
input [31:0] data ;
|
|
input [3:0] be ;
|
|
input make_parity_error ;
|
|
output [2:0] received_termination ;
|
|
begin
|
|
FRAME_int <= #6 1'b1 ;
|
|
IRDY_int <= #6 1'b0 ;
|
|
if (rw)
|
|
begin
|
|
PAR_int <= #6 ^{AD, CBE, make_parity_error} ;
|
|
AD_int <= #6 data ;
|
|
end
|
|
|
|
CBE_int <= #6 be ;
|
|
|
|
@(posedge CLK);
|
|
get_termination(received_termination);
|
|
end
|
|
endtask // subsequent_data_phase
|
|
|
|
task get_termination ;
|
|
output [2:0] received_termination ;
|
|
begin
|
|
while ((TRDY === 1'b1) && (STOP === 1'b1))
|
|
@(posedge CLK) ;
|
|
|
|
if ( DEVSEL !== 1'b0 )
|
|
received_termination = target_abort ;
|
|
else if (TRDY !== 1'b1)
|
|
begin
|
|
if (STOP !== 1'b1)
|
|
received_termination = disconnect ;
|
else
|
else
|
PAR <= #1 1'bz ;
|
received_termination = normal ;
|
|
end
|
|
else
|
|
received_termination = retry ;
|
|
end
|
|
endtask // get_termination
|
|
|
i = 0 ; // Checking for Master Abort
|
task finish_transaction ;
|
while ( (DEVSEL === 1) && (STOP === 1) && (i < 6) )
|
input rw ;
|
|
input make_parity_error ;
|
begin
|
begin
|
|
if (rw)
|
|
PAR_int <= #6 ^{AD, CBE, make_parity_error} ;
|
|
|
|
IRDY_int <= #6 1'b1 ;
|
|
FRAME_en <= #6 1'b0 ;
|
|
AD_en <= #6 1'b0 ;
|
|
CBE_en <= #6 1'b0 ;
|
|
|
@(posedge CLK) ;
|
@(posedge CLK) ;
|
i = i + 1 ;
|
PAR_en <= #6 1'b0 ;
|
|
IRDY_en <= #6 1'b0 ;
|
|
end
|
|
endtask // finish_transaction
|
|
|
|
always@(e_finish_transaction)
|
|
begin
|
|
finish_transaction (write, make_parity_error_after_last_dataphase) ;
|
end
|
end
|
|
|
if ( (DEVSEL !== 1) || (STOP !== 1) )
|
always@(e_transfers_done)
|
begin
|
begin
|
ok = 0 ; // If NO Master abort, then NOT OK!
|
|
|
if (FRAME !== 1'b1)
|
|
begin
|
|
FRAME_int <= #6 1'b1 ;
|
|
IRDY_int <= #6 1'b0 ;
|
|
if (write)
|
|
PAR_int <= #6 ^{CBE, AD} ;
|
|
|
|
@(posedge CLK) ;
|
end
|
end
|
|
|
FRAME <= #1 1'bz ;
|
-> e_finish_transaction ;
|
IRDY <= #1 1'b1 ;
|
end
|
AD <= #1 32'hzzzz_zzzz ;
|
|
CBE <= #1 4'hz ;
|
task insert_waits ;
|
|
input rw ;
|
|
input [2:0] wait_cycles ;
|
|
output [2:0] termination ;
|
|
reg [2:0] wait_cycles_left ;
|
|
reg stop_without_trdy_received ;
|
|
begin
|
|
stop_without_trdy_received = 1'b0 ;
|
|
wait_cycles_left = wait_cycles ;
|
|
|
|
termination = normal ;
|
|
|
|
PAR_int <= #6 ^{AD, CBE} ;
|
|
|
|
for (wait_cycles_left = wait_cycles ; (wait_cycles_left > 0) && !stop_without_trdy_received ; wait_cycles_left = wait_cycles_left - 1'b1)
|
|
begin
|
|
IRDY_int <= #6 1'b1 ;
|
@(posedge CLK) ;
|
@(posedge CLK) ;
|
IRDY <= #1 1'bz ;
|
|
PAR <= #1 1'bz ;
|
PAR_int <= #6 ^{AD, CBE, 1'b1} ;
|
|
|
|
if ((STOP !== 1'b1) && (TRDY !== 1'b0))
|
|
begin
|
|
stop_without_trdy_received = 1'b1 ;
|
|
if (DEVSEL !== 1'b0)
|
|
termination = target_abort ;
|
|
else
|
|
termination = retry ;
|
end
|
end
|
endtask // master_reference
|
end
|
|
end
|
|
endtask // insert_waits
|
endmodule
|
endmodule
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|