519 lines
14 KiB
Coq
519 lines
14 KiB
Coq
|
//+FHDR--------------------------------------------------------------------------------------------------------
|
||
|
// Company:
|
||
|
//-----------------------------------------------------------------------------------------------------------------
|
||
|
// File Name : spi_to_sram_v1.2.v
|
||
|
// Department :
|
||
|
// Author : ZYZ
|
||
|
// Author's Tel :
|
||
|
//-----------------------------------------------------------------------------------------------------------------
|
||
|
// Relese History
|
||
|
// Version Date Author Description
|
||
|
// 1.2 2024-04-02 ZYZ
|
||
|
//-----------------------------------------------------------------------------------------------------------------
|
||
|
// Keywords : 1.replace stream mode of send 32bit data 16 times
|
||
|
// 2.wrdata_reg address is no longer related to csn_active
|
||
|
//-----------------------------------------------------------------------------------------------------------------
|
||
|
// Parameter
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------------------------------------------
|
||
|
// Purpose :
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------------------------------------------
|
||
|
// Target Device:
|
||
|
// Tool versions:
|
||
|
//-----------------------------------------------------------------------------------------------------------------
|
||
|
// Reuse Issues
|
||
|
// Reset Strategy:
|
||
|
// Clock Domains:
|
||
|
// Critical Timing:
|
||
|
// Asynchronous I/F:
|
||
|
// Synthesizable (y/n):
|
||
|
// Other:
|
||
|
//-FHDR--------------------------------------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
|
||
|
module spi_to_sram (
|
||
|
//system port
|
||
|
input clk // System Main Clock
|
||
|
,input spi_rstn // Spi Reset active low
|
||
|
//spi port
|
||
|
,input sclk // Spi Clock
|
||
|
,input csn // Spi Chip Select active low
|
||
|
,input mosi // Spi Mosi
|
||
|
,output miso // Spi Miso
|
||
|
,output miso_oen // Spi Miso output enable
|
||
|
,output error_check // spi form check
|
||
|
|
||
|
,output [31:0] wrdata //write data to sram
|
||
|
,output [24:0] addr //sram address
|
||
|
,output wren //write enable sram
|
||
|
,output rden //rden enable sram
|
||
|
,input [31:0] rddata //read data from sram
|
||
|
|
||
|
);
|
||
|
|
||
|
localparam L = 1'b0,
|
||
|
H = 1'b1;
|
||
|
|
||
|
//3-bits shift register for sclk's rising & falling edges
|
||
|
reg [2 :0] sclk_reg;
|
||
|
wire sclk_p;
|
||
|
wire sclk_n;
|
||
|
|
||
|
//3-bits shift register for csn
|
||
|
reg [4 :0] csn_reg;
|
||
|
wire csn_active;
|
||
|
|
||
|
//2-bits shift register for mosi
|
||
|
reg [1 :0] mosi_reg;
|
||
|
wire mosi_data;
|
||
|
|
||
|
//cmd_reg--> 0:write,1:read
|
||
|
reg cmd_reg;
|
||
|
//rxs_reg
|
||
|
reg rxs_reg;
|
||
|
//addr_reg--> initial address
|
||
|
reg [24 :0] addr_reg;
|
||
|
//rxd_reg --> recive data
|
||
|
reg [31 :0] rxd_reg;
|
||
|
|
||
|
//rx;
|
||
|
reg [9 :0] rxcnt;
|
||
|
wire add_rxcnt;
|
||
|
wire end_rxcnt;
|
||
|
|
||
|
wire wr_times;
|
||
|
reg recv_start;
|
||
|
reg wren_reg;
|
||
|
reg wren_reg_1;
|
||
|
reg [31 :0] wrdata_reg;
|
||
|
|
||
|
//send data
|
||
|
reg [31 :0] txd_reg;
|
||
|
//tx;
|
||
|
reg [9 :0] txcnt;
|
||
|
wire add_txcnt;
|
||
|
wire end_txcnt;
|
||
|
|
||
|
reg trans_start;
|
||
|
|
||
|
//read write address
|
||
|
reg [24:0] rwaddr_reg;
|
||
|
reg address_start;
|
||
|
wire add_addr_wr;
|
||
|
wire add_addr_rd;
|
||
|
|
||
|
//read rddata to txd_reg
|
||
|
reg rd_times;
|
||
|
//read sram
|
||
|
wire rd_sram; //foreread
|
||
|
|
||
|
//output enable
|
||
|
reg miso_reg;
|
||
|
reg miso_oen_reg;
|
||
|
|
||
|
//data form check
|
||
|
reg error_check_reg ;
|
||
|
|
||
|
reg [9:0] frame_len;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//capture the sck
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//sync sclk to the main clock using a 3-bits shift register
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
sclk_reg <= 3'b000;
|
||
|
end
|
||
|
else begin
|
||
|
sclk_reg <= {sclk_reg[1:0],sclk};
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//sclk's rising edges
|
||
|
assign sclk_p = (sclk_reg[2:1] == 2'b01);
|
||
|
|
||
|
//sclk's falling edges
|
||
|
assign sclk_n = (sclk_reg[2:1] == 2'b10);
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//capture the csn
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//sync csn to the main clock using a 3-bits shift register
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
csn_reg <= 5'b11111;
|
||
|
end
|
||
|
else begin
|
||
|
csn_reg <= {csn_reg[3:0],csn};
|
||
|
end
|
||
|
end
|
||
|
|
||
|
// csn is active low
|
||
|
assign csn_active = ~csn_reg[1];
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//capture the mosi
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//sync mosi to the main clock using a 2-bits shift register
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
mosi_reg <= 2'b00;
|
||
|
end
|
||
|
else begin
|
||
|
mosi_reg <= {mosi_reg[0],mosi};
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//mosi_data
|
||
|
assign mosi_data = mosi_reg[1];
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//rxcnt
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
rxcnt <= 10'd0;
|
||
|
end
|
||
|
else if(end_rxcnt) begin
|
||
|
rxcnt <= 10'd0;
|
||
|
end
|
||
|
else if (add_rxcnt)begin
|
||
|
rxcnt <= rxcnt + 1'b1;
|
||
|
end
|
||
|
else begin
|
||
|
rxcnt <= rxcnt;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//add_rxcnt
|
||
|
assign add_rxcnt = sclk_p && csn_active;
|
||
|
assign end_rxcnt = add_rxcnt & (rxcnt == frame_len - 1'b1);
|
||
|
assign wr_times = add_rxcnt & (rxcnt[4:0] == 5'd31) & ~cmd_reg;
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//cmd_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
cmd_reg <= 1'b0;
|
||
|
end
|
||
|
else if(add_rxcnt && rxcnt == 10'd0 ) begin
|
||
|
cmd_reg <= mosi_data;
|
||
|
end
|
||
|
else begin
|
||
|
cmd_reg <= cmd_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//rxs_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L ) begin
|
||
|
rxs_reg <= 1'b0;
|
||
|
end
|
||
|
else if(add_rxcnt && rxcnt == 10'd1) begin
|
||
|
rxs_reg <= mosi_data;
|
||
|
end
|
||
|
else begin
|
||
|
rxs_reg <= rxs_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//addr_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L ) begin
|
||
|
addr_reg <= 25'd0;
|
||
|
end
|
||
|
else if(add_rxcnt && rxcnt <= 10'd26 ) begin
|
||
|
addr_reg <= {addr_reg[23:0],mosi_data};
|
||
|
end
|
||
|
else begin
|
||
|
addr_reg <= addr_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//rxd_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
rxd_reg <= 32'd0;
|
||
|
end
|
||
|
else if(add_rxcnt) begin
|
||
|
rxd_reg <= {rxd_reg[30:0],mosi_data};
|
||
|
end
|
||
|
else begin
|
||
|
rxd_reg <= rxd_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//frame_len
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
frame_len <= 10'd0;
|
||
|
end
|
||
|
else if(add_rxcnt && rxcnt == 10'd2) begin
|
||
|
if(rxs_reg) begin
|
||
|
frame_len <= 10'd544;
|
||
|
end
|
||
|
else begin
|
||
|
frame_len <= 10'd64;
|
||
|
end
|
||
|
end
|
||
|
else begin
|
||
|
frame_len <= frame_len;
|
||
|
end
|
||
|
end
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//recv_start
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
recv_start <= 1'b0;
|
||
|
end
|
||
|
else if(~csn_active )begin
|
||
|
recv_start <= 1'b0;
|
||
|
end
|
||
|
else if(wr_times)begin
|
||
|
recv_start <= 1'b1;
|
||
|
end
|
||
|
else begin
|
||
|
recv_start <= recv_start;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//wren_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
wren_reg <= 1'b0;
|
||
|
end
|
||
|
else begin
|
||
|
wren_reg <= recv_start & wr_times ;
|
||
|
wren_reg_1 <= wren_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//wrdata_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
wrdata_reg <= 32'b0;
|
||
|
end
|
||
|
else if(wren_reg)begin
|
||
|
wrdata_reg <= rxd_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//txcnt
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
txcnt <= 10'd0;
|
||
|
end
|
||
|
else if(end_txcnt) begin
|
||
|
txcnt <= 10'd0;
|
||
|
end
|
||
|
else if (add_txcnt)begin
|
||
|
txcnt <= txcnt + 1'b1;
|
||
|
end
|
||
|
else begin
|
||
|
txcnt <= txcnt;
|
||
|
end
|
||
|
end
|
||
|
//add_txcnt
|
||
|
assign add_txcnt = sclk_n && csn_active;
|
||
|
//end_txcnt
|
||
|
assign end_txcnt = add_txcnt && (txcnt == frame_len - 1'b1) ;
|
||
|
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//rd_times
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
always@(*)begin
|
||
|
if(rxs_reg)begin
|
||
|
rd_times = add_txcnt & (txcnt[4:0] == 5'd31)& (txcnt != 10'd543) & cmd_reg;
|
||
|
end
|
||
|
else begin
|
||
|
rd_times = add_txcnt & (txcnt[4:0] == 5'd31)& (txcnt != 10'd63) & cmd_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//rd_sram foreread
|
||
|
//assign rd_sram = (rd_times) | (add_txcnt & (txcnt[9:0] == 5'd30) & cmd_reg) ;
|
||
|
assign rd_sram = rd_times & cmd_reg;
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//trans_start
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
trans_start <= 1'b0;
|
||
|
end
|
||
|
else if(rd_times)begin
|
||
|
trans_start <= 1'b1;
|
||
|
end
|
||
|
else if(~csn_active)begin
|
||
|
trans_start <= 1'b0;
|
||
|
end
|
||
|
else begin
|
||
|
trans_start <= trans_start;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//txd_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
reg [2:0] rd_times_r;
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
rd_times_r <= 3'b0;
|
||
|
end
|
||
|
else begin
|
||
|
rd_times_r <= {rd_times_r[1:0],rd_times};
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
txd_reg <= 32'h0;
|
||
|
end
|
||
|
else if(rd_times_r[2]) begin
|
||
|
txd_reg <= rddata;
|
||
|
end
|
||
|
else if(add_txcnt && trans_start && txcnt[4:0]!=5'd31) begin
|
||
|
txd_reg <= {txd_reg[30:0],1'b0};
|
||
|
end
|
||
|
else begin
|
||
|
txd_reg <= txd_reg;
|
||
|
end
|
||
|
end
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//address_start
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
address_start <= 1'b0;
|
||
|
end
|
||
|
else if(txcnt == 10'd29)begin
|
||
|
address_start <= 1'b1;
|
||
|
end
|
||
|
else if(~csn_active)begin
|
||
|
address_start <= 1'b0;
|
||
|
end
|
||
|
else begin
|
||
|
address_start <= address_start;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//rwaddr_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
rwaddr_reg <= 25'b0;
|
||
|
end
|
||
|
else if(address_start)begin
|
||
|
if(add_addr_wr)begin
|
||
|
rwaddr_reg <= rwaddr_reg + 3'd4;
|
||
|
end
|
||
|
else if(add_addr_rd)begin
|
||
|
rwaddr_reg <= rwaddr_reg + 3'd4;
|
||
|
end
|
||
|
else begin
|
||
|
rwaddr_reg <= rwaddr_reg;
|
||
|
end
|
||
|
end
|
||
|
else begin
|
||
|
rwaddr_reg <= addr_reg;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
assign add_addr_wr = rxs_reg & wren_reg_1 ;
|
||
|
assign add_addr_rd = rxs_reg & rd_sram ;
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//miso_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
miso_reg <= 1'b0;
|
||
|
end
|
||
|
else begin
|
||
|
miso_reg <= txd_reg[31];
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//miso_oen_reg
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
miso_oen_reg <= 1'b1;
|
||
|
end
|
||
|
else begin
|
||
|
miso_oen_reg <= ~(trans_start & cmd_reg);
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//error_check
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
always @(posedge clk or negedge spi_rstn) begin
|
||
|
if(spi_rstn == L) begin
|
||
|
error_check_reg <= 1'b0;
|
||
|
end
|
||
|
else if( (rxcnt != 0 || txcnt != 0)&&(~csn_active) )begin
|
||
|
error_check_reg <= 1'b1;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//Outputs signals
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//wren
|
||
|
assign wren = wren_reg_1 ;
|
||
|
//wrdata
|
||
|
assign wrdata = wrdata_reg;
|
||
|
//rden
|
||
|
assign rden = rd_sram ;
|
||
|
//addr
|
||
|
assign addr = rwaddr_reg;
|
||
|
//miso
|
||
|
assign miso = miso_reg;
|
||
|
//miso_oen
|
||
|
assign miso_oen = miso_oen_reg;
|
||
|
//error_check
|
||
|
assign error_check = error_check_reg;
|
||
|
|
||
|
endmodule
|
||
|
|
||
|
|