How to resolve this error

** Error: (vlog-13069) E:/uvmp/sequence_item.sv(1): near “uvm_sequence_item”: syntax error, unexpected IDENTIFIER.

** Error: E:/uvmp/sequence_item.sv(1): Error in class extension specification.

In reply to Sree N :

** Error: (vlog-13069) E:/uvmp/sequence_item.sv(1): near “uvm_sequence_item”: syntax error, unexpected IDENTIFIER.

** Error: E:/uvmp/sequence_item.sv(1): Error in class extension specification.

It seems you did not import the uvm_pkg.

//top module
include "uvm_macros.svh" include “spi_pkg.sv”
include "spi_if.sv" //include “uvm_pkg.sv”
//-------------------------------------------------------------
module test;
import uvm_pkg::;
import spi_pkg::
;
//import my_package::*;
spi_if master(clock); // Interface declaration
spi_if slave(clock); // Interface declaration

/------------------SPI master core--------------------------- /
spi top (
/
tb to DUT connection /
.wb_clk_i(clock),
.wb_rst_i(rstn),
.wb_adr_i(master.adr[4:0]),
.wb_dat_i(master.dout),
.wb_sel_i(master.sel),
.wb_we_i(master.we),
.wb_stb_i(master.stb),
.wb_cyc_i(master.cyc),
.wb_dat_o(master.din),
.wb_ack_o(master.ack),
.wb_err_o(master.err),
.wb_int_o(master.intp),
.scan_in0(scan_in0),
.scan_out0(scan_out0),
.scan_en(scan_en),
.test_mode(test_mode),
/
master ito slave connection /
.ss_pad_o(ss),
.sclk_pad_o(sclk),
.mosi_pad_o(mosi),
.miso_pad_i(miso),
.tip(master.pit));
/
------------------SPI slave core---------------------------
/
spi_slave spi_slave (
/* tb to DUT connection /
.wb_clk_i(clock),
.wb_rst_i(rstn),
.wb_adr_i(slave.adr[4:0]),
.wb_dat_i(slave.dout),
.wb_sel_i(slave.sel),
.wb_we_i(slave.we),
.wb_stb_i(slave.stb),
.wb_cyc_i(slave.cyc),
.wb_dat_o(slave.din ),
.wb_ack_o(slave.ack),
.wb_err_o(slave.err),
.wb_int_o(slave.intp),
.scan_in0(scan_in0),
.scan_en(scan_en),
.test_mode(test_mode),
.scan_out0(scan_out0),
/
slave to master connection */
.ss_pad_i(ss),
.sclk_pad_i(sclk),
.mosi_pad_i(mosi),
.miso_pad_o(miso));
//-------------------------------------------------------------
initial begin
$timeformat(-9,2,“ns”,16);
//$timeformat [ ( units_number , precision_number , suffix_string , minimum_field_width ) ];
$set_coverage_db_name(“spi”);
ifdef SDFSCAN $sdf_annotate("sdf/spi_tsmc18_scan.sdf",test.top); endif
generate_clock();
reg_intf_to_config_db();
initalize_dut();
// reset_dut(); // could also be carried out inside pre_reset_phase
run_test();
end

// --------------------------------------------------------------
task generate_clock();
fork
forever begin
clock =LOW; #(CLOCK_PERIOD/2); clock =HIGH;
#(CLOCK_PERIOD/2);
end
join_none
endtask:generate_clock

//-------------------------------------------------------------

function void reg_intf_to_config_db();
// Registers the Interface in the configuration block so that other blocks can use it retrived using get
uvm_config_db#(virtual spi_if)::set(null, “" , “m_if” , master);
uvm_config_db#(virtual spi_if)::set(null, "
” , “s_if” , slave);
endfunction : reg_intf_to_config_db

//-------------------------------------------------------------

function void initalize_dut();
test_mode = 1’b0;
scan_in0 = 1’b0;
scan_in1 = 1’b0;
scan_en = 1’b0;
endfunction : initalize_dut

//-------------------------------------------------------------

task reset_dut();
rstn <= LOW; repeat (RESET_PERIOD)@( posedge clock); rstn <= HIGH;
repeat (RESET_PERIOD)@( posedge clock);
rstn = `LOW;
//->RST_DONE;
endtask : reset_dut
//-------------------------------------------------------------
endmodule : test

//test module
class spi_test extends uvm_test;

//-------------------------------------------------------------
uvm_component_utils(spi_test) spi_env env; spi_sequence h_seq; //Constructor function new(string name=" spi_test " , uvm_component parent); super.new(name,parent); endfunction : new //Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); uvm_info(get_full_name() ,"Build phase called in spi_test " ,UVM_LOW)
/* Build environment component*/
env=spi_env::type_id::create(“env” , this);
endfunction : build_phase
//Connect Phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
uvm_info(get_full_name() ,"Connect phase called in spi_test " ,UVM_LOW) endfunction : connect_phase //Reset Phase task reset_phase(uvm_phase phase); phase.raise_objection(this); rstn <=LOW;
repeat (RESET_PERIOD) @(posedge clock);
rstn <=HIGH; repeat (RESET_PERIOD) @(posedge clock); rstn =LOW;
phase.drop_objection(this);
endtask : reset_phase
//Main Phase
virtual task main_phase(uvm_phase phase);
`uvm_info(get_full_name() ,“in main phase” ,UVM_LOW)
phase.raise_objection(this);
h_seq=spi_sequence::type_id::create(“h_seq”);
repeat (100)
h_seq.start(env.agent.sequencer);
phase.drop_objection(this);
endtask : main_phase
endclass : spi_test

//env module
class spi_env extends uvm_env;
//-------------------------------------------------------------
`uvm_component_utils(spi_env)
spi_agent agent;
spi_scoreboard scoreboard;

//Constructor
function new(string name=“spi_env” ,uvm_component parent);
super.new(name,parent);
endfunction : new

//Build Phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_full_name (),“Build phase called in spi_environment” ,UVM_LOW)
/* Build agent and scoreboard components */
agent=spi_agent::type_id::create(“agent” , this);
scoreboard=spi_scoreboard::type_id::create(“scoreboard” , this);
endfunction : build_phase

//Connect Phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info(get_full_name() ,“Connect phase called in spi_environment” ,UVM_LOW)
/* Connect the analysis port for monitor and driver respectively with scorboard */
agent.monitor.dut_out_pkt.connect(scoreboard.mon2sb);
agent.driver.dut_in_pkt.connect(scoreboard.drv2sb);
endfunction : connect_phase
//-------------------------------------------------------------
endclass : spi_env

class spi_monitor extends uvm_monitor;
uvm_component_utils(spi_monitor) spi_vif m_vif , s_vif; spi_sequence_item packet; uvm_analysis_port #(spi_sequence_item)dut_out_pkt; //Constructor function new(string name=" spi_monitor " ,uvm_component parent); super.new(name , parent); dut_out_pkt=new(" dut_out_pkt " , this); endfunction : new //Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); uvm_info(get_full_name(),“Build phase called in spi_monitor " ,UVM_LOW)
if (!uvm_config_db#(virtual spi_if)::get(this , “” , “m_if” , m_vif))
uvm_fatal ("NO_VIF" ,{" virtual interface must be set for : " ,get_full_name() ,".m_vif"}) if (!uvm_config_db#(virtual spi_if)::get(this , "" , "s_if",s_vif )) uvm_fatal(“NO_VIF” ,{“virtual interface must be set for : " , get_full_name() ,”.s_vif”})
endfunction : build_phase
//Run Phase
task run_phase(uvm_phase phase);
packet=spi_sequence_item::type_id::create(“packet”);
wait (m_vif.monitor_cb.pit==1’b1) // wait_to_start
forever begin
wait(m_vif.monitor_cb.pi ==1’b0) // wait_to_complete
wb_bfm::wb_read(m_vif , 1, SPI_RX_0 , packet.out_master_data);
wb_bfm::wb_read(s_vif , 1, SPI_RX_0 , packet.out_slave_data);
dut_out_pkt.write(packet);
wait (m_vif.monitor_cb.pit ==1’b1); // wait_to_start
end
endtask : run_phase
endclass : spi_monitor

class spi_driver extends uvm_driver #(spi_sequence_item);
uvm_component_utils(spi_driver) spi_vif m_vif , s_vif; spi_sequence_item packet; uvm_analysis_port#(spi_sequence_item)dut_in_pkt; //Constructor function new(string name="spi_monitor" ,uvm_component parent); super.new(name , parent); dut_in_pkt=new("dut_in_pkt " , this); endfunction : new //Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); uvm_info(get_full_name() ,“Build phase called in spi_driver " ,UVM_LOW)
if(!uvm_config_db#(virtual spi_if)::get(this , “” , “m_if " , m_vif))
uvm_fatal("NO_VIF" ,{" virtual interface must be set for : " , get_full_name() ,".m_vif"}) if(!uvm_config_db#(virtual spi_if)::get(this , "" , " s_if " , s_vif ) ) uvm_fatal (“NO_VIF” ,{” virtual interface must be set for : " , get_full_name () ,” . s_vif "})
endfunction : build_phase
//Run Phase
task run_phase(uvm_phase phase);
packet=spi_sequence_item::type_id::create("packet ");
wb_bfm::wb_reset(m_vif);
wb_bfm::wb_reset(s_vif);
fork
forever begin
seq_item_port.get_next_item(req);
drive_transfer(req);
$cast(packet,req.clone());
packet=req;
dut_in_pkt.write(packet);
seq_item_port.item_done();
wait(m_vif.monitor_cb.pit==1’b0);
end
join_none
endtask : run_phase
task drive_transfer(spi_sequence_item seq);
wb_bfm::wb_write(m_vif , 0, SPI_DIVIDE , seq.divider_reg); // set divider register
wb_bfm::wb_write(m_vif , 0, SPI_SS , seq.slave_select_reg); // set ss 0
wb_bfm::wb_write(m_vif , 0, SPI_TX_0 , seq.in_master_data); // set master data register
wb_bfm::wb_write(m_vif , 0, SPI_CTRL, seq.master_ctrl_reg); // set master ctrl register
wb_bfm::wb_write(s_vif, 0, SPI_CTRL, seq.slave_ctrl_reg); // set slave ctrl register
wb_bfm::wb_write(s_vif, 0, SPI_TX_0 , seq.in_slave_data); // set slave data register
wb_bfm::wb_write(m_vif , 0, SPI_CTRL, seq.start_dut_reg); // start data transfer
endtask : drive_transfer
endclass : spi_driver

class spi_sequencer extends uvm_sequencer#(spi_sequence_item);
`uvm_component_utils(spi_sequencer)
//Constructor
function new(string name=" spi_sequencer " ,uvm_component parent);
super.new(name , parent);
endfunction : new
endclass : spi_sequencer

class spi_sequence extends uvm_sequence #(spi_sequence_item);
`uvm_object_utils(spi_sequence)
//Constructor
function new(string name=“spi_sequence”);
super.new(name);
endfunction : new
//Task Body
virtual task body();
req=spi_sequence_item::type_id::create(“req”);
start_item(req);
configure_dut_register();
set_dut_data();
finish_item(req);
endtask : body
virtual function void configure_dut_register();
assert(req.randomize() with
{
req.master_ctrl_reg == 32’h00002208;
req.slave_ctrl_reg == 32’h00000200;
req.divider_reg == 32’h00000000;
req.slave_select_reg == 32’h00000001;
req.start_dut_reg == 32’h00000320;
});
endfunction : configure_dut_register
virtual function void set_dut_data();
assert (req.randomize() with {
req.divider_reg == 32’h00000000;
req.master_ctrl_reg == 32’h00002208;
req.slave_ctrl_reg == 32’h00000200;
req.slave_select_reg == 32’h00000001;
req.start_dut_reg == 32’h00000320;
// req.in_master_data == 32’h87654321;
// req.in_slave_data == 32’h11223344;
req.exp_master_data == req.in_slave_data;
req.exp_slave_data == req.in_master_data;
});
endfunction : set_dut_data
endclass : spi_sequence

class spi_sequence_item extends uvm_sequence_item;
/* Register configuration */
rand logic [31:0]master_ctrl_reg;
rand logic [31:0]slave_ctrl_reg;
rand logic [31:0]divider_reg;
rand logic [31:0]slave_select_reg;
rand logic [31:0]start_dut_reg;
/*DUT output /
logic [31:0]out_master_data;
logic [31:0]out_slave_data;
/
Expected data */
rand logic [31:0]exp_master_data;
rand logic [31:0]exp_slave_data;
/*DUT input */
rand logic [31:0]in_master_data;
rand logic [31:0]in_slave_data;
logic [31:0] q;
uvm_object_utils_begin(spi_sequence_item) uvm_field_int(master_ctrl_reg,UVM_ALL_ON)
uvm_field_int(slave_ctrl_reg,UVM_ALL_ON) uvm_field_int(divider_reg,UVM_ALL_ON)
uvm_field_int(slave_select_reg,UVM_ALL_ON) uvm_field_int(start_dut_reg,UVM_ALL_ON)
uvm_field_int(out_master_data,UVM_ALL_ON) uvm_field_int(out_slave_data,UVM_ALL_ON)
uvm_field_int(exp_master_data,UVM_ALL_ON) uvm_field_int(exp_slave_data,UVM_ALL_ON)
uvm_field_int(in_master_data,UVM_ALL_ON) uvm_field_int(in_slave_data,UVM_ALL_ON)
uvm_field_int(q,UVM_ALL_ON) uvm_object_utils_end
//Constructor
function new(string name=“spi_sequence_item”);
super.new(name);
endfunction : new
endclass : spi_sequence_item

class spi_scoreboard extends uvm_scoreboard;
uvm_component_utils(spi_scoreboard) uvm_analysis_imp_decl(_exp_pkt)
uvm_analysis_imp_decl(_act_pkt) uvm_analysis_imp_exp_pkt#(spi_sequence_item , spi_scoreboard)drv2sb; uvm_analysis_imp_act_pkt#(spi_sequence_item , spi_scoreboard)mon2sb; spi_sequence_item drv_pkt[$]; spi_sequence_item mon_pkt[$]; spi_sequence_item ip_pkt; spi_sequence_item op_pkt; static string report_tag; spi_coverage spi_covg; int pass = 0; int fail = 0; //Constructor function new(string name=" spi_scoreboard " , uvm_component parent); super.new(name , parent); report_tag=$sformatf ("%0s" ,name); drv2sb=new("drv2sb" , this); mon2sb=new("mon2sb" , this); endfunction : new //Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); uvm_info(get_full_name() ,"Build phase called in spi_scoreboard " ,UVM_LOW)
spi_covg=spi_coverage::type_id::create("spi_covg " , this);
endfunction : build_phase
//Connect Phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info(get_full_name(),"Connect phase called in spi_scoreboard " ,UVM_LOW)
endfunction : connect_phase

function void write_exp_pkt(spi_sequence_item tmp_pkt );
spi_sequence_item pkt;
$cast(pkt , tmp_pkt . clone () );
// ‘uvm_info ( report_tag , $sformatf (" Received packet from driver %0s " , pkt . sprint () ) ,UVM_LOW)
drv_pkt.push_back(pkt);
uvm_test_done.raise_objection(this);
endfunction : write_exp_pkt

function void write_act_pkt(spi_sequence_item tmp_pkt);
spi_sequence_item pkt;
$cast(pkt,tmp_pkt.clone());
// uvm_info(report_tag , $sformatf("Received packet from DUT %0s " , pkt.sprint()),UVM_LOW) mon_pkt.push_back(pkt); endfunction : write_act_pkt //Run Phase task run_phase(uvm_phase phase); // fork forever begin wait(mon_pkt.size()!=0); op_pkt=mon_pkt.pop_front(); ip_pkt=drv_pkt.pop_front(); //if(drv_pkt.size()==0) //uvm_error("Expected packet was not received in scoreboard " ,UVM_LOW)
perform_check(ip_pkt , op_pkt);
perform_coverage(ip_pkt);
uvm_test_done.drop_objection(this);
end
// join_none
// disable fork;
endtask : run_phase

function void perform_coverage(spi_sequence_item pkt);
spi_covg.perform_coverage(pkt);
endfunction : perform_coverage

function void perform_check(spi_sequence_item ip_pkt , spi_sequence_item op_pkt);
if(ip_pkt . exp_master_data==op_pkt . out_master_data && ip_pkt . exp_slave_data==op_pkt . out_slave_data)
begin
//uvm_info ( get_full_name () ," Master PASSED" ,UVM_MEDIUM) //uvm_info ( get_full_name () ," Slave PASSED" ,UVM_MEDIUM)
pass++;
end
else
begin
uvm_info(get_full_name() , $sformatf ("Slave FAILED: exp data=%0h and out data=%0h" , ip_pkt . exp_slave_data , op_pkt . out_slave_data ) ,UVM_MEDIUM) uvm_info(get_full_name() , $sformatf (“Master FAILED: exp data=%0h and out master data=%0h” , ip_pkt . exp_master_data , op_pkt . out_master_data ) ,UVM_MEDIUM)
fail ++;
end
endfunction : perform_check
function void extract_phase (uvm_phase phase ) ;
endfunction : extract_phase
function void report_phase (uvm_phase phase ) ;
if(fail ==0)
begin
$display(“----------------------------------32bit–MSB First–TX: posedge–RX: negedge--------------------------------”);
$display(“------------------------------------------------TEST PASSED-----------------------------------------------”);
$display(“********************************************************************************************************** “);
uvm_report_info (“Scoreboard Report” , $sformatf(” Trasactions PASS = %0d FAIL = %0d” ,pass , fail ) ,UVM_MEDIUM);
$display(“********************************************************************************************************** “);
$display(” ---------------------------------------------------------------------------------------------------------- “);
$display(” ---------------------------------------------------------------------------------------------------------- “);
end
else
begin
$display(”----------------------------------32bit–MSB First–TX: posedge–RX: negedge--------------------------------”);
$display(“------------------------------------------------TEST FAILED-----------------------------------------------”);
$display(“********************************************************************************************************** “);
uvm_report_info (“Scoreboard Report” , $sformatf (” Trasactions PASS = %0d FAIL = %0d” ,pass , fail ) ,UVM_MEDIUM);
$display(“**********************************************************************************************************”);
$display(" ---------------------------------------------------------------------------------------------------------- “);
$display(” ---------------------------------------------------------------------------------------------------------- ");
end
endfunction : report_phase
endclass : spi_scoreboard

class spi_coverage extends uvm_component;
`uvm_component_utils(spi_coverage)
spi_sequence_item c_pkt;
//Coverage Details
covergroup spi_trans_cg;
cp_dut_mosi : coverpoint c_pkt.exp_master_data
{
bins byte7 = {[0:255]};
bins byte15= {[256:65535]};
bins byte23= {[65536:16777215]};
bins byte31= {[16777216:$]};
}
endgroup : spi_trans_cg
//Constructor
function new(string name=“spi_covg” , uvm_component parent= null);
super.new(name , parent);
spi_trans_cg = new();
endfunction : new
//Perform Coverage
function void perform_coverage(spi_sequence_item pkt);
this.c_pkt=pkt;
spi_trans_cg.sample();
endfunction : perform_coverage
endclass : spi_coverage

class spi_agent extends uvm_agent;
'uvm_component_utils(spi_agent)
spi_sequencer sequencer;
spi_monitor monitor;
spi_driver driver;
spi_vif m_vif , s_vif;
//Constructor
function new(string name=“spi_agent”,uvm_component parent);
super.new(name , parent );
endfunction : new
//Build Phase
function void build_phase (uvm_phase phase);
super.build_phase(phase);
uvm_info(get_full_name(),"Build phase called in spi_agent ",UVM_LOW) if(!uvm_config_db#(virtual spi_if)::get(this , "" , "m_if " , m_vif)) uvm_fatal(“NO_VIF” ,{“virtual interface must be set for : " , get_full_name() ,”.m_vif"})
if(!uvm_config_db#(virtual spi_if)::get(this , “” , “s_if” , s_vif))
uvm_fatal("NO_VIF" ,{"virtual interface must be set for :" , get_full_name() ,".s_vif"}) sequencer=spi_sequencer::type_id::create("sequencer" , this); driver =spi_driver::type_id::create(" driver " , this); driver.m_vif=m_vif; driver.s_vif=s_vif; monitor=spi_monitor::type_id::create("monitor" , this); monitor.m_vif=m_vif; monitor.s_vif=s_vif; endfunction : build_phase //Coonect Phase function void connect_phase(uvm_phase phase); super.connect_phase(phase); uvm_info(get_full_name(),"Connect phase called in spi_agent " ,UVM_LOW)
driver.seq_item_port.connect(sequencer.seq_item_export);
endfunction : connect_phase
endclass : spi_agent

include "spi_defines.v" include “timescale.v”
module spi(
/Wishbone signals /
wb_clk_i , wb_rst_i , wb_adr_i , wb_dat_i , wb_dat_o , wb_sel_i ,
wb_we_i , wb_stb_i , wb_cyc_i , wb_ack_o , wb_err_o , wb_int_o ,
/SPI signals /
ss_pad_o , sclk_pad_o , mosi_pad_o , miso_pad_i ,
/Scan Insertion /
scan_in0 , scan_en , test_mode , scan_out0 , tip);
/
----------------------------Wishbone signals --------------------------------------
/
input wb_clk_i; // master clock input
input wb_rst_i; // synchronous active high reset
input [4:0] wb_adr_i; // lower address bits
input [32-1:0] wb_dat_i; // databus input
output [32-1:0] wb_dat_o; // databus output
input [3:0] wb_sel_i; // byte select inputs
input wb_we_i; // write enable input
input wb_stb_i; // stobe / core select signal
input wb_cyc_i; // valid bus cycle input
output wb_ack_o; // bus cycle acknowledge output
output wb_err_o; // termination w/ error
output wb_int_o; // interrupt request signal output
/
---------------------------------SPI signals --------------------------------------
/
output [SPI_SS_NB-1:0] ss_pad_o; // slave select output sclk_pad_o; // serial clock output mosi_pad_o; // master out slave in input miso_pad_i; // master in slave out //input reset; // system reset //input clk; // system clock input scan_in0; // test scan mode data input input scan_en; // test scan mode enable input test_mode; // test mode select output scan_out0; // test scan mode data output output tip; /*--------------------------------------------------------------------------------*/ reg [32-1:0]wb_dat_o; reg [32-1:0]wb_dat; reg wb_ack_o; reg wb_int_o; reg [SPI_CTRL_BIT_NB-1:0]ctrl;
reg [SPI_DIVIDER_LEN-1:0]divider; reg [SPI_SS_NB-1:0]ss;
reg scan_out0;
// Internal signals
wire [SPI_MAX_CHAR-1:0]rx; // Rx register wire rx_negedge; // miso is sampled on negative edge wire tx_negedge; // mosi is driven on negative edge wire [SPI_CHAR_LEN_BITS-1:0]char_len; // char len
wire go; // go
wire lsb; // lsb first on line
wire ie; // interrupt enable
wire ass; // automatic slave select
wire spi_divider_sel; // divider register select
wire spi_ctrl_sel; // ctrl register select
wire [3:0] spi_tx_sel; // tx_l register select
wire spi_ss_sel; // ss register select
reg tip; // transfer in progress
wire pos_edge; // recognize posedge of sclk
wire neg_edge; // recognize negedge of sclk
wire last_bit; // marks last character bit
//-----------------------------------------------------------------------------------
spi_clock_gen clock_gen(.clk_in(wb_clk_i) , .rst(wb_rst_i) , .go(go) , .enable(tip) , .last_clk(last_bit) , .divider(divider) , .clk_out(sclk_pad_o) , .pos_edge(pos_edge) , .neg_edge(neg_edge));
// . scan_in0 ( scan_in0 ) , . scan_en ( scan_en ) , . test_mode ( test_mode ) , . scan_out0 ( scan_out0 ) , . reset ( reset ) , . clk ( clk ) ) ;
//-----------------------------------------------------------------------------------
spi_shift shift(.clk_shift(wb_clk_i) , .rst(wb_rst_i) , .len(char_len[ SPI_CHAR_LEN_BITS-1:0]) , .latch(spi_tx_sel [3:0] & {4{wb_we_i}}) , .byte_sel(wb_sel_i) , .lsb(lsb) , .go(go) , .pos_edge(pos_edge) , .neg_edge(neg_edge) , .rx_negedge(rx_negedge) , .tx_negedge(tx_negedge) , .tip(tip) , .last(last_bit) ,.p_in( wb_dat_i ) , .p_out(rx) ,.s_clk(sclk_pad_o) , .s_in(miso_pad_i) , .s_out(mosi_pad_o)); //. scan_in0 ( scan_in0 ) , . scan_en ( scan_en ) , . test_mode ( test_mode ) , . scan_out0 ( scan_out0 ) , . reset ( reset ) , . clk ( clk ) ) ; /*----------------------------------Address decoder -----------------------------------*/ assign spi_divider_sel = wb_cyc_i & wb_stb_i & ( wb_adr_i [SPI_OFS_BITS] == SPI_DIVIDE) ; assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & ( wb_adr_i [SPI_OFS_BITS] == SPI_CTRL) ; assign spi_tx_sel [0] = wb_cyc_i & wb_stb_i & ( wb_adr_i [SPI_OFS_BITS] == SPI_TX_0) ; assign spi_tx_sel [1] = wb_cyc_i & wb_stb_i & ( wb_adr_i [SPI_OFS_BITS] == SPI_TX_1) ; assign spi_tx_sel [2] = wb_cyc_i & wb_stb_i & ( wb_adr_i [SPI_OFS_BITS] == SPI_TX_2) ; assign spi_tx_sel [3] = wb_cyc_i & wb_stb_i & ( wb_adr_i [SPI_OFS_BITS] == SPI_TX_3) ; assign spi_ss_sel = wb_cyc_i & wb_stb_i & ( wb_adr_i [SPI_OFS_BITS] == SPI_SS) ; /*-----------------------------Read from registers -------------------------------------*/ always @( wb_adr_i or rx or ctrl or divider or ss ) begin case ( wb_adr_i [SPI_OFS_BITS])
ifdef SPI_MAX_CHAR_128 SPI_RX_0: wb_dat = rx [31:0];
SPI_RX_1: wb_dat = rx [63:32]; SPI_RX_2: wb_dat = rx [95:64];
SPI_RX_3: wb_dat = {{128-SPI_MAX_CHAR{1’b0}}, rx [`SPI_MAX_CHAR-1:96]};
`else
`ifdef SPI_MAX_CHAR_64
`SPI_RX_0: wb_dat = rx [31:0];
`SPI_RX_1: wb_dat = {{64-`SPI_MAX_CHAR{1’b0}}, rx [`SPI_MAX_CHAR-1:32]};
`SPI_RX_2: wb_dat = 32’b0;
`SPI_RX_3: wb_dat = 32’b0;
`else
`SPI_RX_0: wb_dat = {{32-`SPI_MAX_CHAR{1’b0}}, rx [`SPI_MAX_CHAR-1:0]};
`SPI_RX_1: wb_dat = 32’b0;
`SPI_RX_2: wb_dat = 32’b0;
`SPI_RX_3: wb_dat = 32’b0;
`endif
`endif
`SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1’b0}}, ctrl };
`SPI_DIVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1’b0}}, divider};
`SPI_SS: wb_dat = {{32-`SPI_SS_NB{1’b0}}, ss };
default : wb_dat = 32’bx;
endcase
end
/
---------------------------------Wb data out ----------------------------------------
/
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i)
wb_dat_o <= 32’b0;
else
wb_dat_o <= wb_dat;
end
/------------------------------Wb acknowledge ----------------------------------------/
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i)
wb_ack_o <= 1’b0;
else
wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o;
end
/---------------------------------Wb error ------------------------------------------/
assign wb_err_o = 1’b0;
/---------------------------------Interrupt -----------------------------------------/
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i)
wb_int_o <= 1’b0;
else if ( ie && tip && last_bit && pos_edge )
wb_int_o <= 1’b1;
else if (wb_ack_o)
wb_int_o <= 1’b0;
end
/-------------------------------Divider register -------------------------------------/
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i)
divider <= {`SPI_DIVIDER_LEN{1’b0}};
else if(spi_divider_sel && wb_we_i && ! tip )
begin
`ifdef SPI_DIVIDER_LEN_8
if(wb_sel_i [0])
divider <= wb_dat_i [`SPI_DIVIDER_LEN-1:0];
`endif
`ifdef SPI_DIVIDER_LEN_16
if(wb_sel_i [0])
divider [7:0] <= wb_dat_i [7:0];
if(wb_sel_i [1])
divider[`SPI_DIVIDER_LEN-1:8] <= wb_dat_i [`SPI_DIVIDER_LEN-1:8];
`endif
`ifdef SPI_DIVIDER_LEN_24
if(wb_sel_i [0])
divider [7:0] <= wb_dat_i [7:0];
if(wb_sel_i [1])
divider [15:8] <= wb_dat_i [15:8];
if(wb_sel_i [2])
divider [`SPI_DIVIDER_LEN-1:16] <= wb_dat_i [`SPI_DIVIDER_LEN-1:16];
`endif
`ifdef SPI_DIVIDER_LEN_32
if(wb_sel_i [0])
divider [7:0] <= wb_dat_i [7:0];
if(wb_sel_i [1])
divider [15:8] <= wb_dat_i [15:8];
if(wb_sel_i [2])
divider [23:16] <= wb_dat_i [23:16];
if(wb_sel_i [3])
divider [`SPI_DIVIDER_LEN-1:24] <= wb_dat_i [`SPI_DIVIDER_LEN-1:24];
`endif
end
end
/-------------------------------Ctrl register -------------------------------------/
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i)
ctrl <= {`SPI_CTRL_BIT_NB{1’b0}};
else if(spi_ctrl_sel && wb_we_i && ! tip)
begin
if(wb_sel_i [0])
ctrl [7:0] <= wb_dat_i [7:0] | {7’b0 , ctrl [0]};
if( wb_sel_i [1])
ctrl [`SPI_CTRL_BIT_NB-1:8] <= wb_dat_i [`SPI_CTRL_BIT_NB-1:8];
end
else if( tip && last_bit && pos_edge )
ctrl [`SPI_CTRL_GO] <= 1’b0;
end
/-------------------------------Ctrl register decode ------------------------------/
assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE];
assign go = ctrl[`SPI_CTRL_GO];
assign char_len = ctrl [`SPI_CTRL_CHAR_LEN];
assign lsb = ctrl [`SPI_CTRL_LSB];
assign ie = ctrl [`SPI_CTRL_IE ];
assign ass = ctrl [`SPI_CTRL_ASS];
/------------------------------Slave select register ------------------------------/
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i)
ss <= {`SPI_SS_NB{1’b0}};
else if( spi_ss_sel && wb_we_i && ! tip )
begin
`ifdef SPI_SS_NB_8
if(wb_sel_i [0])
ss <= wb_dat_i [`SPI_SS_NB-1:0];
`endif
`ifdef SPI_SS_NB_16
if(wb_sel_i [0])
ss [7:0] <= wb_dat_i [7:0];
if(wb_sel_i [1])
ss[`SPI_SS_NB-1:8] <= wb_dat_i [`SPI_SS_NB -1:8];
`endif
`ifdef SPI_SS_NB_24
if(wb_sel_i [0])
ss [7:0] <= wb_dat_i [7:0];
if(wb_sel_i [1])
ss [15:8] <= wb_dat_i [15:8];
if(wb_sel_i [2])
ss[`SPI_SS_NB-1:16] <= wb_dat_i [`SPI_SS_NB -1:16];
`endif
`ifdef SPI_SS_NB_32
if ( wb_sel_i [0])
ss [7:0] <= wb_dat_i [7:0];
if ( wb_sel_i [1])
ss [15:8] <= wb_dat_i [15:8];
if ( wb_sel_i [2])
ss [23:16] <= wb_dat_i [23:16];
if ( wb_sel_i [3])
ss [`SPI_SS_NB-1:24] <= wb_dat_i [`SPI_SS_NB -1:24];
`endif
end
end
assign ss_pad_o = ~(( ss & {`SPI_SS_NB{ tip & ass }}) | ( ss & {`SPI_SS_NB{! ass }}) ) ;
endmodule

include "spi_defines.v" include “timescale.v”
module spi_clock_gen(clk_in , rst , go , enable , last_clk , divider , clk_out , pos_edge , neg_edge);
//scan_in0 , scan_en , test_mode , scan_out0 , reset , clk ) ;
input clk_in; // input clock ( system clock )
input rst; // reset
input enable; // clock enable
input go; // start transfer
input last_clk; // last clock
input [SPI_DIVIDER_LEN-1:0]divider; // clock divider ( output clock is divided by this value ) output clk_out; // output clock output pos_edge; // pulse marking positive edge of clk_out output neg_edge; // pulse marking negative edge of clk_out reg clk_out; reg pos_edge; reg neg_edge; reg [SPI_DIVIDER_LEN-1:0] cnt; // clock counter
wire cnt_zero; // conter is equal to zero
wire cnt_one; // conter is equal to one
// -----------------------------------------------------------------------------------
assign cnt_zero = cnt == {SPI_DIVIDER_LEN{1'b0}}; assign cnt_one = cnt == {{SPI_DIVIDER_LEN-1{1’b0}}, 1’b1};
/--------------------------Counter counts half period ------------------------------/
always@(posedge clk_in or posedge rst)
begin
if(rst)
cnt <= {SPI_DIVIDER_LEN{1'b1}}; else begin if (!enable || cnt_zero) cnt <= divider; else cnt <= cnt - {{SPI_DIVIDER_LEN-1{1’b0}},1’b1};
end
end
/----------------clk_out is asserted every other half period ------------------------/
always@(posedge clk_in or posedge rst)
begin
if(rst)
clk_out <= 1’b0;
else
clk_out <= (enable && cnt_zero && (! last_clk || clk_out ) ) ? ~clk_out : clk_out;
end
/------------------------ Pos and neg edge signals ---------------------------------/
always@(posedge clk_in or posedge rst)
begin
if(rst)
begin
pos_edge <= 1’b0;
neg_edge <= 1’b0;
end
else
begin
pos_edge <= ( enable && ! clk_out && cnt_one ) || (!(| divider ) && clk_out ) || ( !(| divider ) && go && ! enable);
neg_edge <= ( enable && clk_out && cnt_one ) || (!(| divider ) && ! clk_out && enable );
end
end
// -----------------------------------------------------------------------------------
endmodule

// ‘define SPI_DIVIDER_LEN_8 14
define SPI_DIVIDER_LEN_16 // ‘define SPI_DIVIDER_LEN_24 // ‘define SPI_DIVIDER_LEN_32 ifdef SPI_DIVIDER_LEN_8
define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8 endif
ifdef SPI_DIVIDER_LEN_16 define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16
endif ifdef SPI_DIVIDER_LEN_24
define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24 endif
ifdef SPI_DIVIDER_LEN_32 28 define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32
endif // ----------------------------------------------------------------------------------- /* 32 Maximum nuber of bits that can be send / received at once . Use SPI_MAX_CHAR for fine tuning the exact number , when using 34 SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8. 35 */ define SPI_MAX_CHAR_128
//define SPI_MAX_CHAR_64 //define SPI_MAX_CHAR_32
//define SPI_MAX_CHAR_24 //define SPI_MAX_CHAR_16
//define SPI_MAX_CHAR_8 43 ifdef SPI_MAX_CHAR_128
define SPI_MAX_CHAR 128 // Can only be set to 128 define SPI_CHAR_LEN_BITS 7
endif ifdef SPI_MAX_CHAR_64
define SPI_MAX_CHAR 64 // Can only be set to 64 define SPI_CHAR_LEN_BITS 6
endif ifdef SPI_MAX_CHAR_32
define SPI_MAX_CHAR 32 // Can be set from 25 to 32 define SPI_CHAR_LEN_BITS 5
endif ifdef SPI_MAX_CHAR_24
define SPI_MAX_CHAR 24 // Can be set from 17 to 24 define SPI_CHAR_LEN_BITS 5
endif ifdef SPI_MAX_CHAR_16
define SPI_MAX_CHAR 16 // Can be set from 9 to 16 define SPI_CHAR_LEN_BITS 4
endif ifdef SPI_MAX_CHAR_8
define SPI_MAX_CHAR 8 // Can be set from 1 to 8 define SPI_CHAR_LEN_BITS 3
endif // ----------------------------------------------------------------------------------- /* 70 Number of device select signals . Use SPI_SS_NB for fine tuning the 71 exact number . 72 */ define SPI_SS_NB_8
//define SPI_SS_NB_16 //define SPI_SS_NB_24
//define SPI_SS_NB_32 ifdef SPI_SS_NB_8
define SPI_SS_NB 8 // Can be set from 1 to 8 endif
ifdef SPI_SS_NB_16 define SPI_SS_NB 16 // Can be set from 9 to 16
endif ifdef SPI_SS_NB_24
define SPI_SS_NB 24 // Can be set from 17 to 24 endif
ifdef SPI_SS_NB_32 define SPI_SS_NB 32 // Can be set from 25 to 32
endif // ----------------------------------------------------------------------------------- /* Bits of WISHBONE address used for partial decoding of SPI registers. */ define SPI_OFS_BITS 4:2
// -----------------------------------------------------------------------------------
/* Register offset /
define SPI_RX_0 0 define SPI_RX_1 1
define SPI_RX_2 2 define SPI_RX_3 3
define SPI_TX_0 0 define SPI_TX_1 1
define SPI_TX_2 2 define SPI_TX_3 3
define SPI_CTRL 4 define SPI_DIVIDE 5
define SPI_SS 6 // ----------------------------------------------------------------------------------- /* Number of bits in ctrl register */ define SPI_CTRL_BIT_NB 14
// -----------------------------------------------------------------------------------
/
Control register bit position */
define SPI_CTRL_ASS 13 define SPI_CTRL_IE 12
define SPI_CTRL_LSB 11 define SPI_CTRL_TX_NEGEDGE 10
define SPI_CTRL_RX_NEGEDGE 9 define SPI_CTRL_GO 8
define SPI_CTRL_RES_1 7 define SPI_CTRL_CHAR_LEN 6:0

interface spi_if(input bit clk);
// Wishbone signals
logic [4:0]adr; // lower address bits
logic [32-1:0]din; // databus input
logic [32-1:0]dout; // databus output
logic [3:0]sel; // byte select inputs
logic we; // write enable input
logic stb; // stobe / core select signal
logic cyc; // valid bus cycle input
logic ack; // bus cycle acknowledge output
logic err; // termination w/ error
logic intp; // interrupt request signal output input
logic pit;
//-------------------------------------------------------------
clocking drive_cb@(posedge clk);
input din , ack , err , intp , pit;
output adr , dout , sel , we, stb , cyc;
endclocking : drive_cb
//-------------------------------------------------------------
clocking monitor_cb@(posedge clk);
input din , ack , err , intp , pit;
output adr , dout , sel , we, stb , cyc;
endclocking : monitor_cb
//-------------------------------------------------------------
endinterface : spi_if

package spi_pkg;
//-------------------------------------------------------------
import uvm_pkg::;
//import my_package::
;
//include "uvm_macros.svh" include “spi_tb_defines.sv”
include "spi_sequence_item.sv" include “wb_bfm.sv”
include "spi_driver.sv" include “spi_monitor.sv”
include "spi_sequencer.sv" include “spi_agent.sv”
include "spi_coverage.sv" include “spi_scoreboard.sv”
include "spi_sequence.sv" include “spi_env.sv”
include "spi_test.sv" //include “spi_slave_model”
endpackage : spi_pkg

include "spi_defines.v" include “timescale.v”
module spi_shift(clk_shift , rst , latch , byte_sel , len , lsb , go , pos_edge , neg_edge , rx_negedge , tx_negedge , tip , last , p_in , p_out , s_clk , s_in , s_out);
// scan_in0 , scan_en , test_mode , scan_out0 , reset , clk ) ;
input clk_shift ; // system clock
input rst; // reset
input [3:0]latch; // latch signal for storing the data in shift register
input [3:0]byte_sel; // byte select signals for storing the data in shift register
input [SPI_CHAR_LEN_BITS-1:0]len; // data len in bits (minus one) input lsb; // lbs first on the line input go; // start stansfer input pos_edge; // recognize posedge of sclk input neg_edge; // recognize negedge of sclk input rx_negedge; // s_in is sampled on negative edge input tx_negedge; // s_out is driven on negative edge output tip; // transfer in progress output last; // last bit input [31:0] p_in; // parallel in output [SPI_MAX_CHAR-1:0]p_out; // parallel out
input s_clk; // serial clock
input s_in; // serial in
output s_out; // serial out
reg s_out;
reg tip;
reg [SPI_CHAR_LEN_BITS:0]cnt; // data bit count reg [SPI_MAX_CHAR-1:0]data; // shift register
wire [SPI_CHAR_LEN_BITS:0]tx_bit_pos; // next bit position wire [SPI_CHAR_LEN_BITS:0]rx_bit_pos; // next bit position
wire rx_clk; // rx clock enable
wire tx_clk; // tx clock enable
// -----------------------------------------------------------------------------------
assign p_out =data;
assign tx_bit_pos = lsb ? {!(| len ) , len} - cnt : cnt - {{ SPI_CHAR_LEN_BITS{1'b0}},1'b1}; assign rx_bit_pos = lsb ? {!(| len ) , len} - ( rx_negedge ? cnt + {{SPI_CHAR_LEN_BITS{1’b0}},1’b1} : cnt ) : ( rx_negedge ? cnt : cnt - {{ SPI_CHAR_LEN_BITS{1'b0}},1'b1}); assign last = !(| cnt ); assign rx_clk = ( rx_negedge ? neg_edge : pos_edge ) && (! last || s_clk ); assign tx_clk = ( tx_negedge ? neg_edge : pos_edge ) && ! last; /*--------------------------Character bit counter -----------------------------------*/ always@(posedge clk_shift or posedge rst) begin if(rst) cnt <= {SPI_CHAR_LEN_BITS+1{1’b0}};
else
begin
if(tip)
cnt <= pos_edge ? ( cnt - {{SPI_CHAR_LEN_BITS{1'b0 }}, 1'b1}) : cnt; else cnt <= !(| len ) ? {1'b1 , {SPI_CHAR_LEN_BITS{1’b0}}} : {1’b0 , len };
end
end
/--------------------------Transfer in progress ------------------------------------/
always@(posedge clk_shift or posedge rst)
begin
if(rst)
tip <= 1’b0;
else if (go && ~tip)
tip <= 1’b1;
else if ( tip && last && pos_edge )
tip <= 1’b0;
end
/------------------------Sending bits to the line ----------------------------------/
always@(posedge clk_shift or posedge rst)
begin
if(rst)
s_out <= 1’b0;
else
s_out <= ( tx_clk || ! tip ) ? data [ tx_bit_pos [SPI_CHAR_LEN_BITS-1:0]] : s_out; end /*-------------------Receiving bits from the line -----------------------------------*/ always@(posedge clk_shift or posedge rst) begin if(rst) data <= {SPI_MAX_CHAR{1’b0}};
ifdef SPI_MAX_CHAR_128 else if(latch [0] && ! tip) begin if(byte_sel [3]) data [31:24] <= p_in [31:24]; if(byte_sel [2]) data [23:16] <= p_in [23:16]; if(byte_sel [1]) data [15:8] <= p_in [15:8]; if(byte_sel [0]) data [7:0] <= p_in [7:0]; end else if(latch [1] && ! tip) begin if(byte_sel [3]) data [63:56] <= p_in [31:24]; if(byte_sel [2]) data [55:48] <= p_in [23:16]; if(byte_sel [1]) data [47:40] <= p_in [15:8]; if(byte_sel [0]) data [39:32] <= p_in [7:0]; end else if( latch [2] && ! tip ) begin if(byte_sel [3]) data [95:88] <= p_in [31:24]; if(byte_sel [2]) data [87:80] <= p_in [23:16]; if(byte_sel [1]) data [79:72] <= p_in [15:8]; if(byte_sel [0]) data [71:64] <= p_in [7:0]; end else if(latch [3] && ! tip) begin if(byte_sel [3]) data [127:120] <= p_in [31:24]; if(byte_sel [2]) 124 data [119:112] <= p_in [23:16]; if(byte_sel [1]) 126 data [111:104] <= p_in [15:8]; if(byte_sel [0]) 128 data [103:96] <= p_in [7:0]; end else
ifdef SPI_MAX_CHAR_64 else if( latch [0] && ! tip ) begin if(byte_sel[3]) data [31:24] <= p_in [31:24]; if(byte_sel[2]) data [23:16] <= p_in [23:16]; if(byte_sel[1]) data [15:8] <= p_in [15:8]; if(byte_sel[0]) data [7:0] <= p_in [7:0]; end else if ( latch [1] && ! tip ) begin if(byte_sel [3]) data [63:56] <= p_in [31:24]; if(byte_sel [2]) data [55:48] <= p_in [23:16]; if(byte_sel [1]) data [47:40] <= p_in [15:8]; if(byte_sel [0]) data [39:32] <= p_in [7:0]; end else
else if( latch [0] && ! tip )
begin
ifdef SPI_MAX_CHAR_8 if(byte_sel [0]) data [SPI_MAX_CHAR-1:0] <= p_in [SPI_MAX_CHAR-1:0]; endif
ifdef SPI_MAX_CHAR_16 if(byte_sel [0]) data [7:0] <= p_in [7:0]; if(byte_sel [1]) data [SPI_MAX_CHAR-1:8] <= p_in [SPI_MAX_CHAR-1:8]; endif
ifdef SPI_MAX_CHAR_24 if(byte_sel [0]) data [7:0] <= p_in [7:0]; if(byte_sel [1]) data [15:8] <= p_in [15:8]; if(byte_sel [2]) data [SPI_MAX_CHAR-1:16] <= p_in [SPI_MAX_CHAR -1:16]; endif
ifdef SPI_MAX_CHAR_32 if(byte_sel [0]) data [7:0] <= p_in [7:0]; if(byte_sel [1]) data [15:8] <= p_in [15:8]; if(byte_sel [2]) data [23:16] <= p_in [23:16]; if(byte_sel [3]) data [SPI_MAX_CHAR-1:24] <= p_in [SPI_MAX_CHAR -1:24]; endif
end
endif endif
else
data [rx_bit_pos [SPI_CHAR_LEN_BITS-1:0]] <= rx_clk ? s_in : data [ rx_bit_pos [SPI_CHAR_LEN_BITS-1:0]];
end
// -----------------------------------------------------------------------------------
endmodule

include "spi_defines.v" include “timescale.v”

// -----------------------------------------------------------------------------------
module spi_slave (
// Wishbone signals
wb_clk_i , wb_rst_i , wb_adr_i , wb_dat_i , wb_dat_o , wb_sel_i ,
wb_we_i , wb_stb_i , wb_cyc_i , wb_ack_o , wb_err_o , wb_int_o ,
// SPI signals
ss_pad_i , sclk_pad_i , mosi_pad_i , miso_pad_o ,
// Scan Insertion
scan_in0 , scan_en , test_mode , scan_out0);
//, reset ,clk);
// Wishbone signals 22 input wb_clk_i ;
// master clock input
input wb_clk_i;
input wb_rst_i; // synchronous active high reset
input [4:0] wb_adr_i; // lower address bits
input [32-1:0] wb_dat_i; // databus input
output [32-1:0] wb_dat_o; // databus output
input [3:0] wb_sel_i; // byte select inputs
input wb_we_i; // write enable input
input wb_stb_i; // stobe / core select signal
input wb_cyc_i; // valid bus cycle input
output wb_ack_o; // bus cycle acknowledge output
output wb_err_o; // termination w/ error
output wb_int_o; // interrupt request signal output
// SPI signals
input [SPI_SS_NB-1:0] ss_pad_i; // slave select input sclk_pad_i; // serial clock input mosi_pad_i; // master out slave in output miso_pad_o; // master in slave out input scan_in0; // test scan mode data input input scan_en; // test scan mode enable input test_mode; // test mode select output scan_out0; // test scan mode data output wire rx_negedge; // slave receiving on negedge wire tx_negedge; // slave transmiting on negedge wire spi_tx_sel; // tx_l register select reg [32-1:0] wb_dat_o; reg [32-1:0] wb_dat; reg wb_ack_o; reg wb_int_o; reg [SPI_CTRL_BIT_NB-1:0] ctrl;
reg miso_pad_o;
// -----------------------------------------------------------------------------------
// Address decoder

 assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & ( wb_adr_i [`SPI_OFS_BITS] == `SPI_CTRL); 

 assign rx_negedge = ctrl [`SPI_CTRL_RX_NEGEDGE]; 

 assign tx_negedge = ctrl [`SPI_CTRL_TX_NEGEDGE]; 

 assign char_len = ctrl [`SPI_CTRL_CHAR_LEN]; 

 assign ie = ctrl [`SPI_CTRL_IE ];

 assign spi_tx_sel = wb_cyc_i & wb_stb_i & ( wb_adr_i [`SPI_OFS_BITS] == `SPI_TX_0);

// -----------------------------------------------------------------------------------
// Wb data out

always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
wb_dat_o <= 32’b0;
else
wb_dat_o <= wb_dat;
end
// -----------------------------------------------------------------------------------
// Wb acknowledge
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if ( wb_rst_i )
wb_ack_o <= 1’b0;
else
wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o;
end
// Wb error
assign wb_err_o = 1’b0;
// Interrupt
/*
always @( posedge wb_clk_i or posedge wb_rst_i )
begin
if ( wb_rst_i )
wb_int_o <= 1b0; else if ( ie && ! ss_pad_i && last_bit && pos_edge ) //there needs to be rising edge detector wb_int_o <= 1b1;
else if (wb_ack_o)
wb_int_o <= 1b0; end */ // ----------------------------------------------------------------------------------- // Ctrl register always@(posedge wb_clk_i or posedge wb_rst_i) begin if (wb_rst_i) ctrl <= {SPI_CTRL_BIT_NB{1’b0}};
else if (spi_ctrl_sel && wb_we_i && (!(& ss_pad_i) ) ) // ! ss_pad_i Because during no transfer we go to tristate mode
begin
if (wb_sel_i [0])
ctrl [7:0] <= wb_dat_i [7:0] | {7’b0 , ctrl [0]};
if (wb_sel_i [1])
ctrl [SPI_CTRL_BIT_NB-1:8] <= wb_dat_i [ SPI_CTRL_BIT_NB-1:8];
end
end
// -----------------------------------------------------------------------------------
always@(posedge ( sclk_pad_i && ! rx_negedge ) or negedge ( sclk_pad_i && rx_negedge ) or posedge wb_rst_i or posedge ( wb_clk_i && (&ss_pad_i ) ) )
begin
if (wb_rst_i)
wb_dat <= 32’b0;
else if (!(& ss_pad_i ) )
wb_dat <= {wb_dat [30:0] , mosi_pad_i };
else if ((&ss_pad_i ) && spi_tx_sel )
wb_dat <= wb_dat_i ;
else
wb_dat <= wb_dat ;
end
// -----------------------------------------------------------------------------------
always@(posedge ( sclk_pad_i && ! tx_negedge ) or negedge ( sclk_pad_i && tx_negedge ) )
begin
miso_pad_o <= wb_dat [31];
end
// -----------------------------------------------------------------------------------
endmoduleinclude "spi_defines.v" include “timescale.v”
module spi_shift(clk_shift , rst , latch , byte_sel , len , lsb , go , pos_edge , neg_edge , rx_negedge , tx_negedge , tip , last , p_in , p_out , s_clk , s_in , s_out);
// scan_in0 , scan_en , test_mode , scan_out0 , reset , clk ) ;
input clk_shift ; // system clock
input rst; // reset
input [3:0]latch; // latch signal for storing the data in shift register
input [3:0]byte_sel; // byte select signals for storing the data in shift register
input [SPI_CHAR_LEN_BITS-1:0]len; // data len in bits (minus one) input lsb; // lbs first on the line input go; // start stansfer input pos_edge; // recognize posedge of sclk input neg_edge; // recognize negedge of sclk input rx_negedge; // s_in is sampled on negative edge input tx_negedge; // s_out is driven on negative edge output tip; // transfer in progress output last; // last bit input [31:0] p_in; // parallel in output [SPI_MAX_CHAR-1:0]p_out; // parallel out
input s_clk; // serial clock
input s_in; // serial in
output s_out; // serial out
reg s_out;
reg tip;
reg [SPI_CHAR_LEN_BITS:0]cnt; // data bit count reg [SPI_MAX_CHAR-1:0]data; // shift register
wire [SPI_CHAR_LEN_BITS:0]tx_bit_pos; // next bit position wire [SPI_CHAR_LEN_BITS:0]rx_bit_pos; // next bit position
wire rx_clk; // rx clock enable
wire tx_clk; // tx clock enable
// -----------------------------------------------------------------------------------
assign p_out =data;
assign tx_bit_pos = lsb ? {!(| len ) , len} - cnt : cnt - {{ SPI_CHAR_LEN_BITS{1'b0}},1'b1}; assign rx_bit_pos = lsb ? {!(| len ) , len} - ( rx_negedge ? cnt + {{SPI_CHAR_LEN_BITS{1’b0}},1’b1} : cnt ) : ( rx_negedge ? cnt : cnt - {{ SPI_CHAR_LEN_BITS{1'b0}},1'b1}); assign last = !(| cnt ); assign rx_clk = ( rx_negedge ? neg_edge : pos_edge ) && (! last || s_clk ); assign tx_clk = ( tx_negedge ? neg_edge : pos_edge ) && ! last; /*--------------------------Character bit counter -----------------------------------*/ always@(posedge clk_shift or posedge rst) begin if(rst) cnt <= {SPI_CHAR_LEN_BITS+1{1’b0}};
else
begin
if(tip)
cnt <= pos_edge ? ( cnt - {{SPI_CHAR_LEN_BITS{1'b0 }}, 1'b1}) : cnt; else cnt <= !(| len ) ? {1'b1 , {SPI_CHAR_LEN_BITS{1’b0}}} : {1’b0 , len };
end
end
/--------------------------Transfer in progress ------------------------------------/
always@(posedge clk_shift or posedge rst)
begin
if(rst)
tip <= 1’b0;
else if (go && ~tip)
tip <= 1’b1;
else if ( tip && last && pos_edge )
tip <= 1’b0;
end
/------------------------Sending bits to the line ----------------------------------/
always@(posedge clk_shift or posedge rst)
begin
if(rst)
s_out <= 1’b0;
else
s_out <= ( tx_clk || ! tip ) ? data [ tx_bit_pos [SPI_CHAR_LEN_BITS-1:0]] : s_out; end /*-------------------Receiving bits from the line -----------------------------------*/ always@(posedge clk_shift or posedge rst) begin if(rst) data <= {SPI_MAX_CHAR{1’b0}};
ifdef SPI_MAX_CHAR_128 else if(latch [0] && ! tip) begin if(byte_sel [3]) data [31:24] <= p_in [31:24]; if(byte_sel [2]) data [23:16] <= p_in [23:16]; if(byte_sel [1]) data [15:8] <= p_in [15:8]; if(byte_sel [0]) data [7:0] <= p_in [7:0]; end else if(latch [1] && ! tip) begin if(byte_sel [3]) data [63:56] <= p_in [31:24]; if(byte_sel [2]) data [55:48] <= p_in [23:16]; if(byte_sel [1]) data [47:40] <= p_in [15:8]; if(byte_sel [0]) data [39:32] <= p_in [7:0]; end else if( latch [2] && ! tip ) begin if(byte_sel [3]) data [95:88] <= p_in [31:24]; if(byte_sel [2]) data [87:80] <= p_in [23:16]; if(byte_sel [1]) data [79:72] <= p_in [15:8]; if(byte_sel [0]) data [71:64] <= p_in [7:0]; end else if(latch [3] && ! tip) begin if(byte_sel [3]) data [127:120] <= p_in [31:24]; if(byte_sel [2]) 124 data [119:112] <= p_in [23:16]; if(byte_sel [1]) 126 data [111:104] <= p_in [15:8]; if(byte_sel [0]) 128 data [103:96] <= p_in [7:0]; end else
ifdef SPI_MAX_CHAR_64 else if( latch [0] && ! tip ) begin if(byte_sel[3]) data [31:24] <= p_in [31:24]; if(byte_sel[2]) data [23:16] <= p_in [23:16]; if(byte_sel[1]) data [15:8] <= p_in [15:8]; if(byte_sel[0]) data [7:0] <= p_in [7:0]; end else if ( latch [1] && ! tip ) begin if(byte_sel [3]) data [63:56] <= p_in [31:24]; if(byte_sel [2]) data [55:48] <= p_in [23:16]; if(byte_sel [1]) data [47:40] <= p_in [15:8]; if(byte_sel [0]) data [39:32] <= p_in [7:0]; end else
else if( latch [0] && ! tip )
begin
ifdef SPI_MAX_CHAR_8 if(byte_sel [0]) data [SPI_MAX_CHAR-1:0] <= p_in [SPI_MAX_CHAR-1:0]; endif
ifdef SPI_MAX_CHAR_16 if(byte_sel [0]) data [7:0] <= p_in [7:0]; if(byte_sel [1]) data [SPI_MAX_CHAR-1:8] <= p_in [SPI_MAX_CHAR-1:8]; endif
ifdef SPI_MAX_CHAR_24 if(byte_sel [0]) data [7:0] <= p_in [7:0]; if(byte_sel [1]) data [15:8] <= p_in [15:8]; if(byte_sel [2]) data [SPI_MAX_CHAR-1:16] <= p_in [SPI_MAX_CHAR -1:16]; endif
ifdef SPI_MAX_CHAR_32 if(byte_sel [0]) data [7:0] <= p_in [7:0]; if(byte_sel [1]) data [15:8] <= p_in [15:8]; if(byte_sel [2]) data [23:16] <= p_in [23:16]; if(byte_sel [3]) data [SPI_MAX_CHAR-1:24] <= p_in [SPI_MAX_CHAR -1:24]; endif
end
endif endif
else
data [rx_bit_pos [SPI_CHAR_LEN_BITS-1:0]] <= rx_clk ? s_in : data [ rx_bit_pos [SPI_CHAR_LEN_BITS-1:0]];
end
// -----------------------------------------------------------------------------------
endmodule