OpenCores
URL https://opencores.org/ocsvn/apb2spi/apb2spi/trunk

Subversion Repositories apb2spi

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 7 to Rev 8
    Reverse comparison

Rev 7 → Rev 8

/apb2spi/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
 
/apb2spi/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
/apb2spi/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
/apb2spi/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
/apb2spi/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
/apb2spi/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
/apb2spi/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
/apb2spi/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
*/
/apb2spi/apb_agent/apb_seqs.v
0,0 → 1,6
 
class apb_seq_item extends uvm_sequence_item ;
`uvm_object_utils(apb_seq_item)
 
 
endclass
/apb2spi/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
/apb2spi/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
/apb2spi/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
/apb2spi/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
 
/apb2spi/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
/apb2spi/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
/apb2spi/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
/apb2spi/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
/apb2spi/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
*/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.