URL
https://opencores.org/ocsvn/apb2spi/apb2spi/trunk
Subversion Repositories apb2spi
Compare Revisions
- This comparison shows the changes necessary to convert path
/apb2spi
- from Rev 14 to Rev 15
- ↔ Reverse comparison
Rev 14 → Rev 15
/trunk/tb/env/apb_agent/apb_agent.sv
0,0 → 1,35
|
|
class apb_agent extends uvm_agent; |
`uvm_component_utils(apb_agent) |
|
apb_seqr apb_sqr; |
apb_driver apb_drvr; |
apb_monitor apb_montr; |
apb_env_config apb_env_cfg; |
uvm_analysis_port #(apb_seq_item) apb_agent_ap; |
|
uvm_active_passive_enum is_active=UVM_ACTIVE; |
|
function new(string name, uvm_component parent) |
super.new(name,parent); |
endfunction |
|
|
function build_phase(uvm_phase phase) |
super.build(); |
if(is_active==UVM_ACTIVE)begin |
drvr = apb_driver::type_id::create("drvr",this); |
sqr = apb_sequencer::type_id::create("sqr",this); |
end |
apb_agent_ap = new(); |
//montr = apb_monitor::type_id::create("montr",this); |
//cfg = apb_config::type_id::create("cfg",this); |
endfunction |
|
function connect_phase(); |
endfunction |
|
|
endclass |
|
/trunk/tb/env/apb_agent/apb_driver.sv
0,0 → 1,87
|
class apb_driver extends uvm_driver#(apb_seq_item); |
`uvm_component_utils(apb_driver) |
|
//uvm_analysis_port#(apb_seq_item) apb_ap; |
|
virtual apb_if v_intf; |
apb_seq_item txns; |
|
function new(string name,uvm_component parent); |
super.new(name,parent); |
//apb_ap = new("apb_ap",this); |
endfunction |
|
function void build_phase(uvm_phase phase); |
super.build_phase(phase); |
if(!uvm_config_db #(virtual apb_if)::get(this,"*","apb_vif",v_intf)) |
`uvm_fatal("NO_APB_V_INTF","Virtual interface couldn't be obtained for apb driver") |
else |
`uvm_info("APB_V_INTF","Virtual interface has been obtained driver",UVM_NONE) |
|
txns = apb_seq_item::type_id::create("txns"); |
endfunction |
|
task run_phase(uvm_phase phase); |
v_intf.PENABLE = 1'b0; |
forever begin |
`uvm_info("DRVR_RUN","Inside the run phase of driver",UVM_NONE) |
seq_item_port.get_next_item(txns); |
`uvm_info("DRVR_RUN",$psprintf("After getting the seq_item from seq, value of seq_item is %p",this.txns),UVM_NONE) |
v_intf.PADDR = txns.paddr; |
//repeat(1)@(posedge v_intf.PCLK); |
`uvm_info("DRVR_RUN","After assigning PADDR from sequence_item",UVM_NONE) |
if(txns.pwrite==1'b1)begin |
`uvm_info("DRVR_RUN","Invoking the apb_write task",UVM_NONE) |
apb_write(txns); |
end else begin |
`uvm_info("DRVR_RUN","Invoking the apb_read task",UVM_NONE) |
apb_read(txns); |
end |
repeat(1)@(posedge v_intf.PCLK); |
seq_item_port.item_done(); |
end |
endtask |
|
task apb_write(apb_seq_item txns); |
begin |
@(posedge v_intf.PCLK); |
//wait(v_intf.PREADY==1'b0); |
v_intf.PSEL = 1'b1; |
v_intf.PENABLE = 1'b0; |
v_intf.PADDR = txns.paddr; |
v_intf.PWRITE = txns.pwrite; |
@(posedge v_intf.PCLK); |
v_intf.PENABLE = 1'b1; |
wait(v_intf.PREADY==1'b1); |
v_intf.PWDATA = txns.pwdata; |
wait(v_intf.PREADY==1'b0); |
v_intf.PSEL = 1'b0; |
v_intf.PADDR = 'h0; |
v_intf.PWRITE = 'h0; |
v_intf.PENABLE = 1'b0; |
end |
endtask |
|
task apb_read(apb_seq_item txns); |
begin |
@(posedge v_intf.PCLK); |
//wait(v_intf.PREADY==1'b0); |
v_intf.PSEL = 1'b1; |
v_intf.PENABLE = 1'b0; |
v_intf.PADDR = txns.paddr; |
v_intf.PWRITE = 1'b0; |
repeat(1)@(posedge v_intf.PCLK); |
v_intf.PENABLE = 1'b1; |
wait(v_intf.PREADY==1'b1); |
txns.prdata = v_intf.PRDATA; |
wait(v_intf.PREADY==1'b0); |
v_intf.PSEL = 1'b0; |
v_intf.PADDR = 'h0; |
v_intf.PWRITE = 'h0; |
v_intf.PENABLE = 1'b0; |
end |
endtask |
|
|
endclass |
/trunk/tb/env/apb_agent/apb_env_config.sv
0,0 → 1,7
|
class apb_env_config extends uvm_object; |
`uvm_object_utils(apb_env_config) |
|
function new(string name); |
super.new(name); |
endfunction |
/trunk/tb/env/apb_agent/apb_if.sv
0,0 → 1,14
|
interface apb_if; |
// APB SLAVE PORT INTERFACE |
logic PCLK; |
logic PRESETn; |
logic [`APB_ADDR_WIDTH-1:0 ] PADDR; |
logic PWRITE; |
logic [`NUM_SLV-1:0] PSEL; |
logic PENABLE; |
logic [`APB_DATA_WIDTH-1:0 ] PWDATA; |
logic [`APB_DATA_WIDTH-1:0 ] PRDATA; |
logic PREADY; |
logic TrFr; |
endinterface |
/trunk/tb/env/apb_agent/apb_intf.sv
0,0 → 1,13
|
interface apb_intf; |
logic [3:0] paddr; |
logic pwrite; |
logic [1:0] psel; |
logic penable; |
wire pready; |
logic [31:0] pwdata; |
wire [31:0] prdata; |
logic pclk; |
logic presetn; |
|
endinterface |
/trunk/tb/env/apb_agent/apb_monitor.sv
0,0 → 1,18
|
class apb_monitor extends uvm_monitor; |
`uvm_component_utils(apb_monitor) |
|
uvm_analysis_port#(apb_seq_item) apb_ap; |
virtual apb_if mon_v_intf; |
|
function new(string name="apb_monitor",uvm_component parent); |
super.new(name,parent); |
apb_ap=new("apb_ap",this); |
endfunction |
|
function void build_phase(uvm_phase phase); |
if(!uvm_config_db#(virtual apb_if)::get(this,"*","apb_intf1",mon_v_intf)) |
`uvm_fatal("NO_APB_MON_V_INTF","Virtual interface couldn't be obtained for apb monitor") |
endfunction |
|
endclass |
/trunk/tb/env/apb_agent/apb_seq_item.sv
0,0 → 1,25
|
class apb_seq_item extends uvm_sequence_item; |
|
rand bit [`APB_ADDR_WIDTH-1:0] paddr; |
rand bit pwrite; |
rand bit [`APB_DATA_WIDTH-1:0] pwdata; |
rand bit presetn; |
//bit psel; |
//bit penable; |
//bit pready; |
bit [`APB_DATA_WIDTH-1:0] prdata; |
|
`uvm_object_utils_begin(apb_seq_item) |
`uvm_field_int(paddr,UVM_ALL_ON) |
`uvm_field_int(pwrite,UVM_ALL_ON) |
`uvm_field_int(pwdata,UVM_ALL_ON) |
`uvm_field_int(presetn,UVM_ALL_ON) |
`uvm_object_utils_end |
|
function new(string name=""); |
super.new(name); |
endfunction |
|
|
endclass |
/trunk/tb/env/apb_agent/apb_seqr.sv
0,0 → 1,13
|
typedef uvm_sequencer #(apb_seq_item) apb_seqr; |
/*class apb_seqr extends uvm_sequencer#(apb_seq_item); |
`uvm_component_utils(apb_seqr) |
|
function new(string name,uvm_component parent); |
super.new(name,parent); |
endfunction |
|
|
|
endclass |
*/ |
/trunk/tb/env/apb_agent/apb_seqs.v
0,0 → 1,6
|
class apb_seq_item extends uvm_sequence_item ; |
`uvm_object_utils(apb_seq_item) |
|
|
endclass |
/trunk/tb/env/apb_agent/apb_slave.v
0,0 → 1,50
`timescale 1ns/1ps |
|
module apb_slave(input [3:0] paddr, |
input pwrite, |
input [1:0] psel, |
input penable, |
output reg pready, |
input [31:0] pwdata, |
output reg [31:0] prdata, |
input pclk, |
input presetn); |
|
reg [31:0] spcr,spdr,wr_data; |
|
always@(posedge pclk or negedge presetn) |
if(!presetn) |
pready <= 1'b0; |
else if(penable==1'b1) |
pready <= 1'b1; |
|
always@(posedge pclk or negedge presetn) |
if(!presetn) |
spcr <= 32'h0; |
else if(psel==2'b01 && pready && penable && pwrite && paddr==4'b0001) |
spcr <= pwdata; |
|
always@(posedge pclk or negedge presetn) |
if(!presetn) |
spdr <= 32'h0; |
else if(psel==2'b01 && pready && penable && pwrite && paddr==4'b0010) |
spdr <= pwdata; |
|
always@(posedge pclk or negedge presetn) |
if(!presetn) |
wr_data <= 32'h0; |
else if(psel==2'b01 && pready && penable && pwrite && paddr==4'b0011) |
wr_data <= pwdata; |
|
always@(posedge pclk or negedge presetn) |
if(!presetn) |
prdata <= 32'h0; |
else if(psel==2'b01 && pready && penable && !pwrite && paddr==4'b0001) |
prdata <= spcr; |
else if(psel==2'b01 && pready && penable && !pwrite && paddr==4'b0010) |
prdata <= spdr; |
else if(psel==2'b01 && pready && penable && !pwrite && paddr==4'b0011) |
prdata <= wr_data; |
|
endmodule |
|
/trunk/tb/env/apb_agent/tb.v
0,0 → 1,83
`include "apb_slave.v" |
module tb(); |
|
reg pclk_i; |
reg presetn_i; |
reg [3:0] paddr_i; |
reg pwrite_i; |
reg [1:0] psel_i; // For future implementations using multiple SPIs |
reg penable_i; |
reg [7:0] pwdata_i; |
wire pready_o; |
wire [7:0] prdata_o; |
|
reg [7:0] spi_data_i; |
wire [7:0] spi_data_o; |
reg spi_txn_cmpl_i; |
|
apb_slave a1( |
pclk_i, |
presetn_i, |
paddr_i, |
pwrite_i, |
psel_i, // For future implementations using multiple SPIs |
penable_i, |
pwdata_i, |
pready_o, |
prdata_o, |
|
spi_data_i, |
spi_data_o, |
spi_txn_cmpl_i); |
|
initial |
begin |
presetn_i = 1'b0; |
pclk_i = 1'b0; |
spi_data_i = 'hab; |
#100 presetn_i = 1'b1; |
$dumpfile("rcc.vcd"); |
$dumpvars(0,tb); |
write(); |
read(); |
#100 $finish; |
end |
|
initial |
forever #10 pclk_i = ~pclk_i; |
|
task write(); |
begin |
paddr_i = 'h0; |
@(posedge pclk_i); |
psel_i = 2'b01; |
pwrite_i = 1'b1; |
pwdata_i = $random; |
@(posedge pclk_i); |
penable_i = 1'b1; |
spi_txn_cmpl_i = 1'b0; |
@(posedge pclk_i); |
spi_txn_cmpl_i = 1'b1; |
@(posedge pclk_i); |
penable_i = 1'b0; |
end |
endtask |
|
task read(); |
begin |
paddr_i = 'h0; |
@(posedge pclk_i); |
psel_i = 2'b11; |
pwrite_i = 1'b0; |
spi_data_i= $random; |
|
@(posedge pclk_i); |
penable_i = 1'b1; |
spi_txn_cmpl_i = 1'b0; |
@(posedge pclk_i); |
spi_txn_cmpl_i = 1'b1; |
|
end |
endtask |
|
endmodule |
/trunk/tb/env/apb_agent/transcript
0,0 → 1,17
# Reading pref.tcl |
# // Questa Sim-64 |
# // Version 10.6b linux_x86_64 May 25 2017 |
# // |
# // Copyright 1991-2017 Mentor Graphics Corporation |
# // All Rights Reserved. |
# // |
# // QuestaSim and its associated documentation contain trade |
# // secrets and commercial or financial information that are the property of |
# // Mentor Graphics Corporation and are privileged, confidential, |
# // and exempt from disclosure under the Freedom of Information Act, |
# // 5 U.S.C. Section 552. Furthermore, this information |
# // is prohibited from disclosure under the Trade Secrets Act, |
# // 18 U.S.C. Section 1905. |
# // |
# Loading project apb2spi |
exit |
/trunk/tb/env/spi_agent/spi_agent.sv
0,0 → 1,37
|
class spi_agent extends uvm_agent; |
|
spi_sequencer spi_sqr; |
spi_driver spi_drvr; |
spi_monitor spi_mntr; |
//spi_env_config spi_env_cfg; |
uvm_analysis_port #(spi_seq_item) spi_agent_ap; |
|
`uvm_component_utils(spi_agent) |
|
//uvm_active_passive_enum spi_is_active=UVM_ACTIVE; |
|
function new(string name="spi_agent", uvm_component parent=null); |
super.new(name,parent); |
endfunction |
|
|
function void build_phase(uvm_phase phase); |
super.build_phase(phase); |
// if(spi_is_active==UVM_ACTIVE)begin |
spi_sqr = spi_sequencer::type_id::create("spi_sqr",this); |
spi_drvr = spi_driver::type_id::create("spi_drvr",this); |
// end |
spi_agent_ap = new("spi_agent_ap",this); |
spi_mntr = spi_monitor::type_id::create("spi_mntr",this); |
endfunction |
|
function void connect_phase(uvm_phase phase); |
// if(spi_is_active==UVM_ACTIVE)begin |
spi_drvr.seq_item_port.connect(spi_sqr.seq_item_export); |
// end |
spi_mntr.spi_ap.connect(spi_agent_ap); |
endfunction |
|
endclass |
|
/trunk/tb/env/spi_agent/spi_driver.sv
0,0 → 1,50
|
class spi_driver extends uvm_driver#(spi_seq_item); |
`uvm_component_utils(spi_driver) |
|
//uvm_analysis_port#(spi_seq_item) spi_ap; |
|
virtual spi_if v_intf; |
integer cnt=0; |
spi_seq_item txn; |
|
function new(string name,uvm_component parent); |
super.new(name,parent); |
//apb_ap = new("apb_ap",this); |
endfunction |
|
function void build_phase(uvm_phase phase); |
if(!uvm_config_db #(virtual spi_if)::get(this,"","spi_vif",v_intf)) |
`uvm_fatal("NO_SPI_V_INTF","Virtual interface couldn't be obtained for spi driver") |
txn = spi_seq_item::type_id::create("txn"); |
endfunction |
|
task run_phase(uvm_phase phase); |
//txn = spi_seq_item::type_id::create("txn"); |
forever |
begin |
fork |
begin |
txn.rdata = txn.ss0_data; |
wait(v_intf.SS==1'b0); |
for(int i=0;i<=`SPI_REG_WIDTH-1;i++) |
begin |
@(posedge v_intf.SCLK) |
v_intf.MISO = txn.rdata[i]; |
end |
end |
begin |
wait(v_intf.SS==1'b0); |
for(int i=0;i<=`SPI_REG_WIDTH-1;i++) |
begin |
@(posedge v_intf.SCLK) |
txn.wdata[i] = v_intf.MOSI; |
end |
txn.ss0_data = txn.wdata; |
end |
join |
end |
endtask |
|
endclass |
|
/trunk/tb/env/spi_agent/spi_if.sv
0,0 → 1,33
interface spi_if; |
|
logic SCLK; |
logic MISO; |
logic MOSI; |
logic SS; |
|
// SPI INTERFACE |
//if Master/Slave Mode |
/*modport master_slave_mode( |
inout SCLK, |
inout MISO, |
inout MOSI, |
output SS |
);*/ |
|
//if only Master Mode |
modport master_mode( |
output SCLK, |
input MISO, |
output MOSI, |
output SS |
); |
|
//if only Slave Mode |
modport slave_mode( |
input SCLK, |
output MISO, |
input MOSI, |
input SS |
); |
|
endinterface |
/trunk/tb/env/spi_agent/spi_monitor.sv
0,0 → 1,38
|
class spi_monitor extends uvm_monitor; |
`uvm_component_utils(spi_monitor) |
|
uvm_analysis_port#(spi_seq_item) spi_ap; |
virtual spi_if m_v_intf; |
spi_seq_item txn; |
integer cnt=0; |
|
function new(string name="spi_monitor",uvm_component parent); |
super.new(name,parent); |
spi_ap=new("spi_ap",this); |
endfunction |
|
function void build_phase(uvm_phase phase); |
super.build_phase(phase); |
if(!uvm_config_db#(virtual spi_if)::get(this,"*","spi_vif",m_v_intf)) |
`uvm_fatal("NO_SPI_MON_V_INTF","Virtual interface couldn't be obtained for spi monitor") |
endfunction |
|
virtual task run_phase(uvm_phase phase); |
txn = spi_seq_item::type_id::create("txn"); |
forever |
begin |
wait(m_v_intf.SS==1'b0); |
for(int i=0;i<=`SPI_REG_WIDTH-1;i++) |
begin |
@(posedge m_v_intf.SCLK) |
txn.wdata[i] = m_v_intf.MOSI; |
txn.rdata[i] = m_v_intf.MISO; |
cnt++; |
end |
wait(m_v_intf.SS==1'b1); |
spi_ap.write(txn); |
end |
endtask |
|
endclass |
/trunk/tb/env/spi_agent/spi_seq_item.sv
0,0 → 1,15
|
class spi_seq_item extends uvm_sequence_item; |
|
`uvm_object_utils(spi_seq_item) |
|
bit [`SPI_REG_WIDTH-1:0] wdata; |
bit [`SPI_REG_WIDTH-1:0] rdata; |
bit [`SPI_REG_WIDTH-1:0] ss0_data; |
|
function new(string name=""); |
super.new(name); |
endfunction |
|
|
endclass |
/trunk/tb/env/spi_agent/spi_seqr.sv
0,0 → 1,11
|
typedef uvm_sequencer #(spi_seq_item) spi_sequencer; |
/*class spi_seqr extends uvm_sequencer#(spi_seq_item); |
`uvm_component_utils(spi_seqr) |
|
function new(string name,uvm_component parent); |
super.new(name,parent); |
endfunction |
|
endclass |
*/ |