252 lines
5.9 KiB
Verilog
252 lines
5.9 KiB
Verilog
// Relese History
|
|
// Version Date Author Description
|
|
// 0.3 2024-05-29 ZYZ
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Keywords : connect spi-master
|
|
//
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Parameter :
|
|
// cmd[31:0] form:
|
|
// form-v0.2 {WR ,RSV ,ID ,ADDR}
|
|
// [31] [30] [29:25] [24:0]
|
|
//
|
|
// form-v0.3 {WR ,ADDR ,ID ,RSV}
|
|
// [31] [30:6] [5:1] [0]
|
|
//
|
|
// form-v0.2 is defined by design , it has len[31:0];
|
|
// form-v0.3 is produced by spi interface ,it doesn't have len[31:0];
|
|
//
|
|
// size : 256K
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Purpose :
|
|
//
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Target Device:
|
|
// Tool versions:
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Reuse Issues
|
|
// Reset Strategy:
|
|
// Clock Domains:
|
|
// Critical Timing:
|
|
// Asynchronous I/F:
|
|
// Synthesizable (y/n):
|
|
// Other:
|
|
//-FHDR--------------------------------------------------------------------------------------------------------
|
|
module tx_sram(
|
|
input clk,
|
|
input rstn,
|
|
|
|
(* mark_debug="true" *)input [31:0] dina,
|
|
(* mark_debug="true" *)input [15:0] data_length,
|
|
|
|
output [31:0] Nlen,
|
|
output [4 :0] chip_ID,
|
|
output [24:0] address,
|
|
output [31:0] data_out,
|
|
(* mark_debug="true" *)output wr_en,
|
|
(* mark_debug="true" *)output rd_en,
|
|
|
|
(* mark_debug="true" *)input WREADY,
|
|
(* mark_debug="true" *)input RREADY,
|
|
|
|
output data_done_all,
|
|
output data_out_per
|
|
);
|
|
|
|
|
|
parameter width = 32 ;
|
|
parameter depth = 65536 ;
|
|
|
|
//=================================================
|
|
function integer clog2(input integer depth);
|
|
begin
|
|
for(clog2=0;depth>0;clog2=clog2+1)
|
|
depth =depth>>1;
|
|
end
|
|
endfunction
|
|
//=================================================
|
|
|
|
localparam aw = clog2(depth-1);
|
|
|
|
//=================================================
|
|
//wr&rd address
|
|
|
|
(* mark_debug="true" *) reg [aw-1:0]cnta ;
|
|
(* mark_debug="true" *) reg [aw-1:0]cntb ;
|
|
|
|
(* mark_debug="true" *) wire ena ;
|
|
(* mark_debug="true" *) wire enb ;
|
|
(* mark_debug="true" *) wire full ;
|
|
(* mark_debug="true" *) wire [31:0] doutb;
|
|
|
|
//current len of data ,initial value is 0
|
|
(* mark_debug="true" *) reg [31:0]len_current ;
|
|
|
|
//cmd
|
|
(* mark_debug="true" *) reg cmd_s ;
|
|
(* mark_debug="true" *) reg [4:0] chip_ID_reg ;
|
|
(* mark_debug="true" *)reg [24:0]address_reg ;
|
|
always@(posedge clk or negedge rstn)begin
|
|
if(!rstn)begin
|
|
cmd_s <= 1'b0;
|
|
chip_ID_reg <= 5'b0;
|
|
address_reg <= 25'b0;
|
|
end
|
|
else if(cntb == len_current + 2'd1)begin
|
|
cmd_s <= doutb[31];
|
|
chip_ID_reg <= doutb[5:1];
|
|
address_reg <= doutb[30:6];
|
|
end
|
|
else begin
|
|
cmd_s <= cmd_s;
|
|
chip_ID_reg <= chip_ID_reg;
|
|
address_reg <= address_reg;
|
|
end
|
|
end
|
|
assign chip_ID = chip_ID_reg;
|
|
assign address = address_reg;
|
|
|
|
|
|
//len of data_out
|
|
(* mark_debug="true" *) reg [31:0]len_reg ;
|
|
always@(posedge clk or negedge rstn)begin
|
|
if(!rstn)begin
|
|
len_reg <= 32'b0;
|
|
end
|
|
else if(cntb == len_current + 2'd2)begin
|
|
len_reg <= doutb ;
|
|
end
|
|
else begin
|
|
len_reg <= len_reg;
|
|
end
|
|
end
|
|
assign Nlen = len_reg;
|
|
|
|
|
|
//data_out
|
|
(* mark_debug="true" *) reg [31:0]data_out_reg ;
|
|
(* mark_debug="true" *) wire data_out_en ;
|
|
always@(posedge clk or negedge rstn)begin
|
|
if(!rstn)begin
|
|
data_out_reg <= 32'b0;
|
|
end
|
|
else if(data_out_en)begin
|
|
data_out_reg <= doutb ;
|
|
end
|
|
else begin
|
|
data_out_reg <= 32'b0;
|
|
end
|
|
end
|
|
|
|
reg data_out_en_r1;
|
|
always@(posedge clk or negedge rstn)begin
|
|
if(!rstn)begin
|
|
data_out_en_r1 <= 1'b0;
|
|
end
|
|
else begin
|
|
data_out_en_r1 <= data_out_en;
|
|
end
|
|
end
|
|
|
|
assign data_out = data_out_reg;
|
|
assign data_out_en = (cntb >= len_current + 2'd3) & (cntb <= len_current + len_reg + 2'd2);
|
|
|
|
//signal send to spi_master
|
|
assign wr_en = !cmd_s & data_out_en_r1;
|
|
assign rd_en = cmd_s & data_out_en_r1;
|
|
|
|
//signal send to PC
|
|
assign data_out_per = (cntb == len_current + 3'd3 ) ? 1'b1 : 1'b0;
|
|
assign data_done_all = (cntb == data_length-1'b1 | cnta == data_length - 1'b1) ? 1'b1 : 1'b0;
|
|
|
|
//the time ready for writing data and updata len_current
|
|
reg [2:0] wready_reg;
|
|
always @(posedge clk or negedge rstn)
|
|
begin
|
|
if(!rstn ) begin
|
|
wready_reg <= 3'b0;
|
|
end
|
|
else begin
|
|
wready_reg <= {wready_reg[1:0],WREADY};
|
|
end
|
|
end
|
|
assign wready_posedge = wready_reg[1:0] == 2'b01 ? 1'b1 : 1'b0;
|
|
|
|
//updata len_current and cntb
|
|
always@(posedge clk or negedge rstn)begin
|
|
if(!rstn)begin
|
|
len_current <= 32'b0;
|
|
end
|
|
else if( wready_posedge & len_reg != 0)begin
|
|
len_current <= len_current + len_reg + 2'd2 ;
|
|
end
|
|
else begin
|
|
len_current <= len_current;
|
|
end
|
|
end
|
|
|
|
//write address: addra
|
|
//read address: addrb
|
|
always @(posedge clk or negedge rstn)
|
|
begin
|
|
if(!rstn) begin
|
|
cnta <= 'hffff;
|
|
end
|
|
else if(ena) begin
|
|
cnta <= cnta + 1'b1;
|
|
end
|
|
else
|
|
cnta <= cnta ;
|
|
end
|
|
|
|
always @(posedge clk or negedge rstn)
|
|
begin
|
|
if(!rstn ) begin
|
|
cntb <= 'h0 ;
|
|
end
|
|
else if(enb) begin
|
|
cntb <= cntb + 1'b1;
|
|
end
|
|
else if(wready_posedge & len_reg != 0) begin
|
|
cntb <= cntb - 1'b1 ; // better solution?
|
|
end
|
|
else begin
|
|
cntb <= cntb;
|
|
end
|
|
end
|
|
|
|
assign full = (cnta+1'b1 <= data_length )? 1'b0 : 1'b1 ;
|
|
assign ena = !full;
|
|
assign enb = full & (cntb <= data_length ) & WREADY & (cntb <= len_current + len_reg + 2'd2);
|
|
/*
|
|
blk_mem_gen_0 blk_mem_gen_0_inst(
|
|
.clka(clk),
|
|
.ena(1'b1),
|
|
.wea(ena),
|
|
.dina(dina),
|
|
.addra(cnta),
|
|
|
|
.clkb(clk),
|
|
.enb(enb),
|
|
.doutb(doutb),
|
|
.addrb(cntb)
|
|
);
|
|
*/
|
|
spram_model #(
|
|
.width(width),
|
|
.depth(depth)
|
|
)spram_inst(
|
|
.clka(clk),
|
|
.ena(~ena),
|
|
.dina(dina),
|
|
.addra(cnta),
|
|
|
|
.clkb(clk),
|
|
.enb(~enb),
|
|
.doutb(doutb),
|
|
.addrb(cntb)
|
|
);
|
|
|
|
endmodule
|
|
|