blob: 4e99d282c88f54ba379dea63f286a701d9609574 [file] [log] [blame]
/*
Mohamed Shalan (mshalan@aucegypt.edu)
*/
/*
Registers
cfg (W): 0:cpol, 1:cpha, 8-15: clock divider [0x08]
ctrl (W): 0: go, 1:ssb [0x04]
status (R): 0: done [0x10]
datain (W): 0-7: data in [0x00]
datao (R): 0-7: data out [0x00]
*/
`timescale 1ns/1ps
`default_nettype none
module APB_SPI(
input wire PCLK,
input wire PRESETn,
input wire PWRITE,
input wire [31:0] PWDATA,
input wire [31:0] PADDR,
input wire PENABLE,
input PSEL,
output wire PREADY,
output wire [31:0] PRDATA,
input wire MSI,
output wire MSO,
output wire SSn,
output wire SCLK,
output IRQ
);
reg [7:0] SPI_DATAi_REG;
wire [7:0] SPI_DATAo_REG;
reg [1:0] SPI_CTRL_REG;
wire SPI_STATUS_REG;
reg [9:0] SPI_CFG_REG;
reg [0:0] SPI_IM_REG;
wire go, cpol, cpha, done, busy, csb;
wire [7:0] datai, datao, clkdiv;
// The Control Register -- Size: 2 -- offset: 4
always @(posedge PCLK, negedge PRESETn)
begin
if(!PRESETn)
begin
SPI_CTRL_REG <= 2'b0;
end
else if(PENABLE & PWRITE & PREADY & PSEL & PADDR[2] & ~PADDR[3] & ~PADDR[4])
SPI_CTRL_REG <= PWDATA[1:0];
end
// Configuration Register -- Size; 10 -- Offset: 8
always @(posedge PCLK, negedge PRESETn)
begin
if(!PRESETn)
begin
SPI_CFG_REG <= 10'b0;
end
else if(PENABLE & PWRITE & PREADY & PSEL & PADDR[3] & ~PADDR[2] & ~PADDR[4])
SPI_CFG_REG <= PWDATA[9:0];
end
// Data Register -- Size: 8 -- Offset: 0
always @(posedge PCLK, negedge PRESETn)
begin
if(!PRESETn)
begin
SPI_DATAi_REG <= 8'b0;
end
else if(PENABLE & PWRITE & PREADY & PSEL & ~PADDR[2] & ~PADDR[3] & ~PADDR[4])
SPI_DATAi_REG <= PWDATA[7:0];
end
// IM Register -- Size: 1 -- Offset: 0x14
always @(posedge PCLK, negedge PRESETn)
begin
if(!PRESETn)
begin
SPI_IM_REG <= 1'b0;
end
else if(PENABLE & PWRITE & PREADY & PSEL & PADDR[2] & ~PADDR[3] & PADDR[4])
SPI_IM_REG <= PWDATA[0:0];
end
assign datai = SPI_DATAi_REG[7:0];
assign go = SPI_CTRL_REG[0];
assign SSn = ~SPI_CTRL_REG[1];
assign cpol = SPI_CFG_REG[0];
assign cpha = SPI_CFG_REG[1];
assign clkdiv = SPI_CFG_REG[9:2];
assign SPI_STATUS_REG = DONE;
assign SPI_DATAo_REG = datao;
reg DONE;
always @(posedge PCLK, negedge PRESETn)
begin
if(!PRESETn)
begin
DONE <= 1'b0;
end
else if(done)
DONE <= 1'b1;
else if(go)
DONE <= 1'b0;
end
spi_master
#(
.DATA_WIDTH(8),
.CLK_DIVIDER_WIDTH(8)
) SPI_CTRL (
.clk(PCLK),
.resetb(PRESETn),
.CPOL(cpol),
.CPHA(cpha),
.clk_divider(clkdiv),
.go(go),
.datai(datai),
.datao(datao),
//.busy(busy),
.done(done),
.dout(MSI),
.din(MSO),
//.csb(ss),
.sclk(SCLK)
);
assign PRDATA[31:0] = (PADDR[2] & PADDR[4]) ? {31'd0, SPI_IM_REG} :
(PADDR[2]) ? {30'd0,SPI_CTRL_REG} :
(PADDR[3]) ? {{22'd0,SPI_CFG_REG}} :
(PADDR[4]) ? {31'd0,SPI_STATUS_REG} :
{24'd0,SPI_DATAo_REG};
assign PREADY = 1'b1;
assign IRQ = SPI_IM_REG[0] & DONE;
endmodule