Files
BSI-901-fpga-software/c64_pro.srcs/sources_1/rtl/eeg/ads1299_if.v
T
2026-09-11 16:18:36 +08:00

195 lines
5.6 KiB
Verilog

`timescale 1 ns / 1 ps
module ads1299_if#
(
parameter SPI_CLK_DIV = 3 ,
parameter SPI_DATA_WIDTH = 8 ,
parameter SPI_SLAVE_QTY = 2 ,
parameter SPI_CNV_BYTES = 3
)
(
input clk ,
input rst_n ,
input upload_enable ,
input upload_round ,
//------------------------------------------ spi direct communication
input [ 8-1:0] t_cs_n ,
input [ 8-1:0] t_tdata ,
input t_tlast ,
output t_tready ,
input t_tvalid ,
output [ 8-1:0] r_tdata ,
output r_tlast ,
output r_tvalid ,
//------------------------------------------ record stream rx
output reg [32-1:0] cnv_res_tdata ,
output reg cnv_res_tlast ,
input cnv_res_tready ,
output reg cnv_res_tvalid ,
//------------------------------------------ device spi
output [SPI_SLAVE_QTY-1:0] cs ,
output sclk ,
output mosi ,
input miso
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam IDLE = 4'h0 ;
localparam UPLOAD_ST = 4'h1 ;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
wire [ 8-1:0] r_tdata_w ;
wire r_tlast_w ;
wire r_tvalid_w ;
wire [ 8-1:0] res_tdata ;
wire res_tlast ;
wire res_tvalid ;
reg [ 8-1:0] slv_cnt ;
reg [ 8-1:0] r_cnt ;
reg [ 4-1:0] byte_cnt ;
reg [32-1:0] word ;
reg res_tvalid_b ;
reg res_tlast_b ;
reg [ 8-1:0] ch ;
//*****************************************************************************
// Instantiation
//*****************************************************************************
ads1299_spi#
(
.CLK_PERIOD ( 10 ),
.CLK_DIV ( SPI_CLK_DIV ),
.DATA_WIDTH ( SPI_DATA_WIDTH ),
.NO_OF_SLAVES ( SPI_SLAVE_QTY )
)
u_ads1299_spi
(
.clk ( clk ),
.rst_n ( rst_n ),
.t_cs_n ( t_cs_n ),
.t_tdata ( t_tdata ),
.t_tlast ( t_tlast ),
.t_tready ( t_tready ),
.t_tvalid ( t_tvalid ),
.r_tdata ( r_tdata_w ),
.r_tlast ( r_tlast_w ),
.r_tvalid ( r_tvalid_w ),
.cs ( cs ),
.sclk ( sclk ),
.mosi ( mosi ),
.miso ( miso )
);
//*****************************************************************************
// Procedural blocks
//*****************************************************************************
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
res_tvalid_b <= 1'b0;
res_tlast_b <= 1'b0;
end else begin
res_tvalid_b <= res_tvalid;
res_tlast_b <= res_tlast;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
r_cnt <= 0;
else if ( upload_round )
r_cnt <= 0;
else if ( res_tvalid && res_tlast )
r_cnt <= 0;
else if ( res_tvalid )
r_cnt <= r_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
slv_cnt <= 0;
else if ( upload_round )
slv_cnt <= 0;
else if ( res_tvalid && res_tlast )
slv_cnt <= slv_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
byte_cnt <= 0;
else if ( upload_round || r_cnt<SPI_CNV_BYTES )
byte_cnt <= 0;
else if ( res_tvalid ) begin
if ( byte_cnt == SPI_CNV_BYTES )
byte_cnt <= 1;
else
byte_cnt <= byte_cnt + 1'b1;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
word <= 0;
else if ( res_tvalid )
word <= {8'd0, word[15:0], res_tdata};
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cnv_res_tdata <= 0;
cnv_res_tvalid <= 1'b0;
end else if ( res_tvalid_b && byte_cnt == SPI_CNV_BYTES ) begin
cnv_res_tdata <= {ch, word[23:0]};
cnv_res_tvalid <= 1'b1;
end else if ( cnv_res_tready ) begin
cnv_res_tvalid <= 1'b0;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cnv_res_tlast <= 1'b0;
end else if ( res_tvalid_b && res_tlast_b && slv_cnt == SPI_SLAVE_QTY ) begin
cnv_res_tlast <= res_tlast_b;
end else if ( cnv_res_tready ) begin
cnv_res_tlast <= 1'b0;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
ch <= 0;
else if ( upload_round )
ch <= 0;
else if ( res_tvalid_b && byte_cnt == SPI_CNV_BYTES )
ch <= ch + 1'b1;
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
assign r_tdata = (~upload_enable)? r_tdata_w :0;
assign r_tlast = (~upload_enable)? r_tlast_w :0;
assign r_tvalid = (~upload_enable)? r_tvalid_w:0;
assign res_tdata = (upload_enable)? r_tdata_w :0;
assign res_tlast = (upload_enable)? r_tlast_w :0;
assign res_tvalid = (upload_enable)? r_tvalid_w:0;
endmodule