Delete simple_spi_top.v
This commit is contained in:
parent
882e34155b
commit
4f34482209
|
@ -1,335 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// OpenCores MC68HC11E based SPI interface ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2002 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: simple_spi_top.v,v 1.5 2004-02-28 15:59:50 rherveille Exp $
|
||||
//
|
||||
// $Date: 2004-02-28 15:59:50 $
|
||||
// $Revision: 1.5 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.4 2003/08/01 11:41:54 rherveille
|
||||
// Fixed some timing bugs.
|
||||
//
|
||||
// Revision 1.3 2003/01/09 16:47:59 rherveille
|
||||
// Updated clkcnt size and decoding due to new SPR bit assignments.
|
||||
//
|
||||
// Revision 1.2 2003/01/07 13:29:52 rherveille
|
||||
// Changed SPR bits coding.
|
||||
//
|
||||
// Revision 1.1.1.1 2002/12/22 16:07:15 rherveille
|
||||
// Initial release
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Motorola MC68HC11E based SPI interface
|
||||
//
|
||||
// Currently only MASTER mode is supported
|
||||
//
|
||||
|
||||
module simple_spi #(
|
||||
parameter SS_WIDTH = 1
|
||||
)(
|
||||
// 8bit WISHBONE bus slave interface
|
||||
input wire clk_i, // clock
|
||||
input wire rst_i, // reset (synchronous active high)
|
||||
input wire cyc_i, // cycle
|
||||
input wire stb_i, // strobe
|
||||
input wire [2:0] adr_i, // address
|
||||
input wire we_i, // write enable
|
||||
input wire [7:0] dat_i, // data input
|
||||
output reg [7:0] dat_o, // data output
|
||||
output reg ack_o, // normal bus termination
|
||||
output reg inta_o, // interrupt output
|
||||
|
||||
// SPI port
|
||||
output reg sck_o, // serial clock output
|
||||
output [SS_WIDTH-1:0] ss_o, // slave select (active low)
|
||||
output wire mosi_o, // MasterOut SlaveIN
|
||||
input wire miso_i // MasterIn SlaveOut
|
||||
);
|
||||
|
||||
//
|
||||
// Module body
|
||||
//
|
||||
reg [7:0] spcr; // Serial Peripheral Control Register ('HC11 naming)
|
||||
wire [7:0] spsr; // Serial Peripheral Status Register ('HC11 naming)
|
||||
reg [7:0] sper; // Serial Peripheral Extension Register
|
||||
reg [7:0] treg; // Transmit Register
|
||||
reg [SS_WIDTH-1:0] ss_r; // Slave Select Register
|
||||
|
||||
// fifo signals
|
||||
wire [7:0] rfdout;
|
||||
reg wfre, rfwe;
|
||||
wire rfre, rffull, rfempty;
|
||||
wire [7:0] wfdout;
|
||||
wire wfwe, wffull, wfempty;
|
||||
|
||||
// misc signals
|
||||
wire tirq; // transfer interrupt (selected number of transfers done)
|
||||
wire wfov; // write fifo overrun (writing while fifo full)
|
||||
reg [1:0] state; // statemachine state
|
||||
reg [2:0] bcnt;
|
||||
|
||||
//
|
||||
// Wishbone interface
|
||||
wire wb_acc = cyc_i & stb_i; // WISHBONE access
|
||||
wire wb_wr = wb_acc & we_i; // WISHBONE write access
|
||||
|
||||
// dat_i
|
||||
always @(posedge clk_i)
|
||||
if (rst_i)
|
||||
begin
|
||||
spcr <= 8'h10; // set master bit
|
||||
sper <= 8'h00;
|
||||
ss_r <= 0;
|
||||
end
|
||||
else if (wb_wr)
|
||||
begin
|
||||
if (adr_i == 3'b000)
|
||||
spcr <= dat_i | 8'h10; // always set master bit
|
||||
|
||||
if (adr_i == 3'b011)
|
||||
sper <= dat_i;
|
||||
|
||||
if (adr_i == 3'b100)
|
||||
ss_r <= dat_i[SS_WIDTH-1:0];
|
||||
end
|
||||
|
||||
// slave select (active low)
|
||||
assign ss_o = ~ss_r;
|
||||
|
||||
// write fifo
|
||||
assign wfwe = wb_acc & (adr_i == 3'b010) & ack_o & we_i;
|
||||
assign wfov = wfwe & wffull;
|
||||
|
||||
// dat_o
|
||||
always @(posedge clk_i)
|
||||
case(adr_i) // synopsys full_case parallel_case
|
||||
3'b000: dat_o <= spcr;
|
||||
3'b001: dat_o <= spsr;
|
||||
3'b010: dat_o <= rfdout;
|
||||
3'b011: dat_o <= sper;
|
||||
3'b100: dat_o <= {{ (8-SS_WIDTH){1'b0} }, ss_r};
|
||||
default: dat_o <= 0;
|
||||
endcase
|
||||
|
||||
// read fifo
|
||||
assign rfre = wb_acc & (adr_i == 3'b010) & ack_o & ~we_i;
|
||||
|
||||
// ack_o
|
||||
always @(posedge clk_i)
|
||||
if (rst_i)
|
||||
ack_o <= 1'b0;
|
||||
else
|
||||
ack_o <= wb_acc & !ack_o;
|
||||
|
||||
// decode Serial Peripheral Control Register
|
||||
wire spie = spcr[7]; // Interrupt enable bit
|
||||
wire spe = spcr[6]; // System Enable bit
|
||||
wire dwom = spcr[5]; // Port D Wired-OR Mode Bit
|
||||
wire mstr = spcr[4]; // Master Mode Select Bit
|
||||
wire cpol = spcr[3]; // Clock Polarity Bit
|
||||
wire cpha = spcr[2]; // Clock Phase Bit
|
||||
wire [1:0] spr = spcr[1:0]; // Clock Rate Select Bits
|
||||
|
||||
// decode Serial Peripheral Extension Register
|
||||
wire [1:0] icnt = sper[7:6]; // interrupt on transfer count
|
||||
wire [1:0] spre = sper[1:0]; // extended clock rate select
|
||||
|
||||
wire [3:0] espr = {spre, spr};
|
||||
|
||||
// generate status register
|
||||
wire wr_spsr = wb_wr & (adr_i == 3'b001);
|
||||
|
||||
reg spif;
|
||||
always @(posedge clk_i)
|
||||
if (~spe | rst_i)
|
||||
spif <= 1'b0;
|
||||
else
|
||||
spif <= (tirq | spif) & ~(wr_spsr & dat_i[7]);
|
||||
|
||||
reg wcol;
|
||||
always @(posedge clk_i)
|
||||
if (~spe | rst_i)
|
||||
wcol <= 1'b0;
|
||||
else
|
||||
wcol <= (wfov | wcol) & ~(wr_spsr & dat_i[6]);
|
||||
|
||||
assign spsr[7] = spif;
|
||||
assign spsr[6] = wcol;
|
||||
assign spsr[5:4] = 2'b00;
|
||||
assign spsr[3] = wffull;
|
||||
assign spsr[2] = wfempty;
|
||||
assign spsr[1] = rffull;
|
||||
assign spsr[0] = rfempty;
|
||||
|
||||
|
||||
// generate IRQ output (inta_o)
|
||||
always @(posedge clk_i)
|
||||
inta_o <= spif & spie;
|
||||
|
||||
//
|
||||
// hookup read/write buffer fifo
|
||||
fifo4 #(8)
|
||||
rfifo(
|
||||
.clk ( clk_i ),
|
||||
.rst ( ~rst_i ),
|
||||
.clr ( ~spe ),
|
||||
.din ( treg ),
|
||||
.we ( rfwe ),
|
||||
.dout ( rfdout ),
|
||||
.re ( rfre ),
|
||||
.full ( rffull ),
|
||||
.empty ( rfempty )
|
||||
),
|
||||
wfifo(
|
||||
.clk ( clk_i ),
|
||||
.rst ( ~rst_i ),
|
||||
.clr ( ~spe ),
|
||||
.din ( dat_i ),
|
||||
.we ( wfwe ),
|
||||
.dout ( wfdout ),
|
||||
.re ( wfre ),
|
||||
.full ( wffull ),
|
||||
.empty ( wfempty )
|
||||
);
|
||||
|
||||
//
|
||||
// generate clk divider
|
||||
reg [11:0] clkcnt;
|
||||
always @(posedge clk_i)
|
||||
if(spe & (|clkcnt & |state))
|
||||
clkcnt <= clkcnt - 11'h1;
|
||||
else
|
||||
case (espr) // synopsys full_case parallel_case
|
||||
4'b0000: clkcnt <= 12'h0; // 2 -- original M68HC11 coding
|
||||
4'b0001: clkcnt <= 12'h1; // 4 -- original M68HC11 coding
|
||||
4'b0010: clkcnt <= 12'h3; // 16 -- original M68HC11 coding
|
||||
4'b0011: clkcnt <= 12'hf; // 32 -- original M68HC11 coding
|
||||
4'b0100: clkcnt <= 12'h1f; // 8
|
||||
4'b0101: clkcnt <= 12'h7; // 64
|
||||
4'b0110: clkcnt <= 12'h3f; // 128
|
||||
4'b0111: clkcnt <= 12'h7f; // 256
|
||||
4'b1000: clkcnt <= 12'hff; // 512
|
||||
4'b1001: clkcnt <= 12'h1ff; // 1024
|
||||
4'b1010: clkcnt <= 12'h3ff; // 2048
|
||||
4'b1011: clkcnt <= 12'h7ff; // 4096
|
||||
default : clkcnt <= 12'hfff;
|
||||
endcase
|
||||
|
||||
// generate clock enable signal
|
||||
wire ena = ~|clkcnt;
|
||||
|
||||
// transfer statemachine
|
||||
always @(posedge clk_i)
|
||||
if (~spe | rst_i)
|
||||
begin
|
||||
state <= 2'b00; // idle
|
||||
bcnt <= 3'h0;
|
||||
treg <= 8'h00;
|
||||
wfre <= 1'b0;
|
||||
rfwe <= 1'b0;
|
||||
sck_o <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
wfre <= 1'b0;
|
||||
rfwe <= 1'b0;
|
||||
|
||||
case (state) //synopsys full_case parallel_case
|
||||
2'b00: // idle state
|
||||
begin
|
||||
bcnt <= 3'h7; // set transfer counter
|
||||
treg <= wfdout; // load transfer register
|
||||
sck_o <= cpol; // set sck
|
||||
|
||||
if (~wfempty) begin
|
||||
wfre <= 1'b1;
|
||||
state <= 2'b01;
|
||||
if (cpha) sck_o <= ~sck_o;
|
||||
end
|
||||
end
|
||||
|
||||
2'b01: // clock-phase2, next data
|
||||
if (ena) begin
|
||||
sck_o <= ~sck_o;
|
||||
state <= 2'b11;
|
||||
end
|
||||
|
||||
2'b11: // clock phase1
|
||||
if (ena) begin
|
||||
treg <= {treg[6:0], miso_i};
|
||||
bcnt <= bcnt -3'h1;
|
||||
|
||||
if (~|bcnt) begin
|
||||
state <= 2'b00;
|
||||
sck_o <= cpol;
|
||||
rfwe <= 1'b1;
|
||||
end else begin
|
||||
state <= 2'b01;
|
||||
sck_o <= ~sck_o;
|
||||
end
|
||||
end
|
||||
|
||||
2'b10: state <= 2'b00;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign mosi_o = treg[7];
|
||||
|
||||
|
||||
// count number of transfers (for interrupt generation)
|
||||
reg [1:0] tcnt; // transfer count
|
||||
always @(posedge clk_i)
|
||||
if (~spe)
|
||||
tcnt <= icnt;
|
||||
else if (rfwe) // rfwe gets asserted when all bits have been transfered
|
||||
if (|tcnt)
|
||||
tcnt <= tcnt - 2'h1;
|
||||
else
|
||||
tcnt <= icnt;
|
||||
|
||||
assign tirq = ~|tcnt & rfwe;
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue