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/branches
- from Rev 4 to Rev 10
- ↔ Reverse comparison
Rev 4 → Rev 10
/current_cpy/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 |
|
|
/current_cpy/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 |
*/ |
/current_cpy/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 |