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

Subversion Repositories spi_verilog_master_slave

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /spi_verilog_master_slave/trunk
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/testbench/TB_SPI_MasSlv.v
0,0 → 1,144
////////////////////////////////////////////////////////////////////////////////
//// ////
//// Project Name: SPI (Verilog) ////
//// ////
//// Module Name: Master_Slave_Testbench ////
//// ////
//// ////
//// This file is part of the Ethernet IP core project ////
//// http://opencores.com/project,spi_verilog_master_slave ////
//// ////
//// Author(s): ////
//// Santhosh G (santhg@opencores.org) ////
//// ////
//// Refer to Readme.txt for more information ////
//// ////
////////////////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2014, 2015 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
////////////////////////////////////////////////////////////////////////////////
 
`timescale 1ns/10ps
module TB_SPI_MasSlv;
reg rstb;
reg clk = 1'b0;
reg mlb = 1'b0;
reg start = 1'b0;
reg [7:0] m_tdat = 8'b00000000;
reg [1:0] cdiv = 0;
wire din;
wire ss;
wire sck;
wire dout;
wire Mdone;
wire [7:0] Mrdata;
reg ten = 1'b0;
reg [7:0] s_tdata = 8'b00000000;
wire SLVdone;
wire [7:0] SLVrdata;
 
parameter PERIOD = 50;
parameter real DUTY_CYCLE = 0.5;
parameter OFFSET = 100;
initial begin // Clock process for clk
#OFFSET;
forever
begin
clk = 1'b0;
#(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;
#(PERIOD*DUTY_CYCLE);
end
end
// to end simulation
initial #10000 $stop;
 
//uut MASTER instantiation
spi_master MAS (
.rstb(rstb),
.clk(clk),
.mlb(mlb),
.start(start),
.tdat(m_tdat),
.cdiv(cdiv),
.din(din),
.ss(ss),
.sck(sck),
.dout(dout),
.done(Mdone),
.rdata(Mrdata));
//uut SLAVE instantiation
spi_slave SLV (
.rstb(rstb),
.ten(ten),
.tdata(s_tdata),
.mlb(mlb),
.ss(ss),
.sck(sck),
.sdin(dout),
.sdout(din),
.done(SLVdone),
.rdata(SLVrdata));
 
// timed contrl signals
initial begin
#10 rstb = 1'b0;
#100;
rstb = 1'b1;start = 1'b0;
m_tdat = 8'b01111100;
cdiv = 2'b00;
#100 start = 1'b1;ten=1; //s_tdata=8'hAC;
#100 start = 1'b0;
 
#1800 mlb = 1'b1; cdiv=2'b01; m_tdat=8'b00011100;//s_tdata=8'h64;
#100 start = 1'b1;
#100 start = 1'b0;
#2202;
#100 start = 1'b1;
#100 start = 1'b0;
#2000;
 
m_tdat=~m_tdat;
#100 start = 1'b1;
#100 start = 1'b0;
#2000;
 
end
 
always @ (rstb or Mrdata) begin
if(rstb==0)
s_tdata = 8'hAA;
else
begin
# 10 s_tdata = Mrdata;
end
end
 
endmodule
 
 
/rtl/spi_slave.v
0,0 → 1,111
////////////////////////////////////////////////////////////////////////////////
//// ////
//// Project Name: SPI (Verilog) ////
//// ////
//// Module Name: spi_slave ////
//// ////
//// ////
//// This file is part of the Ethernet IP core project ////
//// http://opencores.com/project,spi_verilog_master_slave ////
//// ////
//// Author(s): ////
//// Santhosh G (santhg@opencores.org) ////
//// ////
//// Refer to Readme.txt for more information ////
//// ////
////////////////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2014, 2015 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
////////////////////////////////////////////////////////////////////////////////
/* SPI MODE 3
CHANGE DATA (sdout) @ NEGEDGE SCK
read data (sdin) @posedge SCK
*/
module spi_slave (rstb,ten,tdata,mlb,ss,sck,sdin, sdout,done,rdata);
input rstb,ss,sck,sdin,ten,mlb;
input [7:0] tdata;
output sdout; //slave out master in
output reg done;
output reg [7:0] rdata;
 
reg [7:0] treg,rreg;
reg [3:0] nb;
wire sout;
assign sout=mlb?treg[7]:treg[0];
assign sdout=( (!ss)&&ten )?sout:1'bz; //if 1=> send data else TRI-STATE sdout
 
 
//read from sdout
always @(posedge sck or negedge rstb)
begin
if (rstb==0)
begin rreg = 8'h00; rdata = 8'h00; done = 0; nb = 0; end //
else if (!ss) begin
if(mlb==0) //LSB first, in@msb -> right shift
begin rreg ={sdin,rreg[7:1]}; end
else //MSB first, in@lsb -> left shift
begin rreg ={rreg[6:0],sdin}; end
//increment bit count
nb=nb+1;
if(nb!=8) done=0;
else begin rdata=rreg; done=1; nb=0; end
end //if(!ss)_END if(nb==8)
end
 
//send to sdout
always @(negedge sck or negedge rstb)
begin
if (rstb==0)
begin treg = 8'hFF; end
else begin
if(!ss) begin
if(nb==0) treg=tdata;
else begin
if(mlb==0) //LSB first, out=lsb -> right shift
begin treg = {1'b1,treg[7:1]}; end
else //MSB first, out=msb -> left shift
begin treg = {treg[6:0],1'b1}; end
end
end //!ss
end //rstb
end //always
 
endmodule
/*
if(mlb==0) //LSB first, out=lsb -> right shift
begin treg = {treg[7],treg[7:1]}; end
else //MSB first, out=msb -> left shift
begin treg = {treg[6:0],treg[0]}; end
*/
 
 
/*
force -freeze sim:/SPI_slave/sck 0 0, 1 {25 ns} -r 50 -can 410
run 405ns
noforce sim:/SPI_slave/sck
force -freeze sim:/SPI_slave/sck 1 0
*/
/rtl/spi_master.v
0,0 → 1,164
////////////////////////////////////////////////////////////////////////////////
//// ////
//// Project Name: SPI (Verilog) ////
//// ////
//// Module Name: spi_master ////
//// ////
//// ////
//// This file is part of the Ethernet IP core project ////
//// http://opencores.com/project,spi_verilog_master_slave ////
//// ////
//// Author(s): ////
//// Santhosh G (santhg@opencores.org) ////
//// ////
//// Refer to Readme.txt for more information ////
//// ////
////////////////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2014, 2015 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
////////////////////////////////////////////////////////////////////////////////
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SPI MODE 3
CHANGE DATA @ NEGEDGE
read data @posedge
 
RSTB-active low asyn reset, CLK-clock, T_RB=0-rx 1-TX, mlb=0-LSB 1st 1-msb 1st
START=1- starts data transmission cdiv 0=clk/4 1=/8 2=/16 3=/32
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module spi_master(rstb,clk,mlb,start,tdat,cdiv,din, ss,sck,dout,done,rdata);
input rstb,clk,mlb,start;
input [7:0] tdat; //transmit data
input [1:0] cdiv; //clock divider
input din;
output reg ss;
output reg sck;
output reg dout;
output reg done;
output reg [7:0] rdata; //received data
 
parameter idle=2'b00;
parameter send=2'b10;
parameter finish=2'b11;
reg [1:0] cur,nxt;
 
reg [7:0] treg,rreg;
reg [3:0] nbit;
reg [4:0] mid,cnt;
reg shift,clr;
 
//FSM i/o
always @(start or cur or nbit or cdiv or rreg) begin
nxt=cur;
clr=0;
shift=0;//ss=0;
case(cur)
idle:begin
if(start==1)
begin
case (cdiv)
2'b00: mid=2;
2'b01: mid=4;
2'b10: mid=8;
2'b11: mid=16;
endcase
shift=1;
done=1'b0;
nxt=send;
end
end //idle
send:begin
ss=0;
if(nbit!=8)
begin shift=1; end
else begin
rdata=rreg;done=1'b1;
nxt=finish;
end
end//send
finish:begin
shift=0;
ss=1;
clr=1;
nxt=idle;
end
default: nxt=finish;
endcase
end//always
 
//state transistion
always@(negedge clk or negedge rstb) begin
if(rstb==0)
cur<=finish;
else
cur<=nxt;
end
 
//setup falling edge (shift dout) sample rising edge (read din)
always@(negedge clk or posedge clr) begin
if(clr==1)
begin cnt=0; sck=1; end
else begin
if(shift==1) begin
cnt=cnt+1;
if(cnt==mid) begin
sck=~sck;
cnt=0;
end //mid
end //shift
end //rst
end //always
 
//sample @ rising edge (read din)
always@(posedge sck or posedge clr ) begin // or negedge rstb
if(clr==1) begin
nbit=0; rreg=8'hFF; end
else begin
if(mlb==0) //LSB first, din@msb -> right shift
begin rreg={din,rreg[7:1]}; end
else //MSB first, din@lsb -> left shift
begin rreg={rreg[6:0],din}; end
nbit=nbit+1;
end //rst
end //always
 
always@(negedge sck or posedge clr) begin
if(clr==1) begin
treg=8'hFF; dout=1;
end
else begin
if(nbit==0) begin //load data into TREG
treg=tdat; dout=mlb?treg[7]:treg[0];
end //nbit_if
else begin
if(mlb==0) //LSB first, shift right
begin treg={1'b1,treg[7:1]}; dout=treg[0]; end
else//MSB first shift LEFT
begin treg={treg[6:0],1'b1}; dout=treg[7]; end
end
end //rst
end //always
 
 
endmodule

powered by: WebSVN 2.1.0

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