上传PL工程
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module ads1299_arrange#
|
||||
(
|
||||
parameter CLK_PERIOD = 10 ,
|
||||
parameter SPI_DATA_WIDTH = 8 ,
|
||||
parameter SPI_TRANS_PERIOD = 2000 , //Unit: ns
|
||||
parameter SPI_RDATAC_PERIOD = 2000 //Unit: ns
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst_n ,
|
||||
|
||||
input [ 8-1:0] send_cs_n ,
|
||||
input send_enable ,
|
||||
input [ 8-1:0] send_length ,
|
||||
input [32-1:0] send_data_array ,
|
||||
output reg recv_data_en ,
|
||||
output [32-1:0] recv_data_array ,
|
||||
|
||||
output reg [ 8-1:0] t_cs_n ,
|
||||
output reg [ 8-1:0] t_tdata ,
|
||||
output reg t_tlast ,
|
||||
input t_tready ,
|
||||
output reg t_tvalid ,
|
||||
|
||||
input [ 8-1:0] r_tdata ,
|
||||
input r_tlast ,
|
||||
input r_tvalid ,
|
||||
|
||||
input rdatac_enable ,
|
||||
output reg cnv_start ,
|
||||
input cnv_drdy ,
|
||||
output upload_round
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// localparam definition
|
||||
//*****************************************************************************
|
||||
localparam T_PERIOD = SPI_TRANS_PERIOD/CLK_PERIOD ;
|
||||
|
||||
localparam IDLE = 4'd0 ;
|
||||
localparam TRANS_ST = 4'd1 ;
|
||||
localparam WAIT_ST = 4'd2 ;
|
||||
localparam RDATAC_ST = 4'd3 ;
|
||||
localparam REVC_1_ST = 4'd4 ;
|
||||
localparam REVC_2_ST = 4'd5 ;
|
||||
|
||||
localparam RDATAC_BYTES = 27 ;
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg [ 4-1:0] cstate ;
|
||||
reg [ 4-1:0] nstate ;
|
||||
|
||||
reg [16-1:0] time_cnt ;
|
||||
reg [ 8-1:0] t_cnt ;
|
||||
reg [ 8-1:0] r_cnt ;
|
||||
reg [ 4-1:0] cnv_drdy_r ;
|
||||
wire drdy ;
|
||||
|
||||
wire [ 8-1:0] send_data[3:0] ;
|
||||
reg [ 8-1:0] recv_data[3:0] ;
|
||||
|
||||
genvar i;
|
||||
|
||||
//*****************************************************************************
|
||||
// Instantiation
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Procedural blocks
|
||||
//*****************************************************************************
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
cnv_drdy_r <= 0;
|
||||
else
|
||||
cnv_drdy_r <= {cnv_drdy_r[2:0], cnv_drdy};
|
||||
end
|
||||
|
||||
always@( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) cstate <= IDLE;
|
||||
else cstate <= nstate;
|
||||
end
|
||||
|
||||
always@( * ) begin
|
||||
case ( cstate )
|
||||
IDLE:
|
||||
if ( send_enable )
|
||||
nstate <= TRANS_ST;
|
||||
else if ( rdatac_enable )
|
||||
nstate <= RDATAC_ST;
|
||||
else
|
||||
nstate <= IDLE;
|
||||
TRANS_ST:
|
||||
nstate <= WAIT_ST;
|
||||
WAIT_ST:
|
||||
if ( time_cnt == 0 ) begin
|
||||
if ( t_cnt == send_length )
|
||||
nstate <= IDLE;
|
||||
else
|
||||
nstate <= TRANS_ST;
|
||||
end else begin
|
||||
nstate <= WAIT_ST;
|
||||
end
|
||||
RDATAC_ST:
|
||||
if ( ~rdatac_enable )
|
||||
nstate <= IDLE;
|
||||
else if ( drdy )
|
||||
nstate <= REVC_1_ST;
|
||||
else
|
||||
nstate <= RDATAC_ST;
|
||||
REVC_1_ST:
|
||||
if ( t_tvalid && t_tready && t_cnt == RDATAC_BYTES-1 )
|
||||
nstate <= REVC_2_ST;
|
||||
else
|
||||
nstate <= REVC_1_ST;
|
||||
REVC_2_ST:
|
||||
if ( t_tvalid && t_tready && t_cnt == RDATAC_BYTES-1 )
|
||||
nstate <= RDATAC_ST;
|
||||
else
|
||||
nstate <= REVC_2_ST;
|
||||
default:
|
||||
nstate <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
t_cnt <= 0;
|
||||
end else if ( (cstate == IDLE && nstate == TRANS_ST) || (cstate == RDATAC_ST && nstate == REVC_1_ST) || (cstate == REVC_1_ST && nstate == REVC_2_ST) ) begin
|
||||
t_cnt <= 0;
|
||||
end else if ( t_tvalid && t_tready ) begin
|
||||
t_cnt <= t_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
time_cnt <= 0;
|
||||
end else if ( nstate == TRANS_ST ) begin
|
||||
time_cnt <= T_PERIOD - 1'b1;
|
||||
end else if ( time_cnt != 0 ) begin
|
||||
time_cnt <= time_cnt - 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
cnv_start <= 1'b0;
|
||||
end else if ( nstate == IDLE ) begin
|
||||
cnv_start <= 1'b0;
|
||||
end else if ( nstate == RDATAC_ST ) begin
|
||||
cnv_start <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
t_cs_n <= 0;
|
||||
end else if ( cstate == REVC_1_ST ) begin
|
||||
t_cs_n <= 0;
|
||||
end else if ( cstate == REVC_2_ST ) begin
|
||||
t_cs_n <= 1;
|
||||
end else begin
|
||||
t_cs_n <= send_cs_n;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
t_tdata <= 0;
|
||||
t_tvalid <= 1'b0;
|
||||
end else if ( cstate == TRANS_ST ) begin
|
||||
t_tdata <= send_data[t_cnt];
|
||||
t_tvalid <= 1'b1;
|
||||
end else if ( cstate == REVC_1_ST && nstate == REVC_1_ST ) begin
|
||||
t_tdata <= 0;
|
||||
t_tvalid <= 1'b1;
|
||||
end else if ( cstate == REVC_2_ST && nstate == REVC_2_ST ) begin
|
||||
t_tdata <= 0;
|
||||
t_tvalid <= 1'b1;
|
||||
end else begin
|
||||
t_tvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
t_tlast <= 1'b0;
|
||||
end else if ( cstate == TRANS_ST && t_cnt == send_length-1 ) begin
|
||||
t_tlast <= 1'b1;
|
||||
end else if ( (cstate == REVC_1_ST || cstate == REVC_2_ST) && t_cnt == RDATAC_BYTES-1 ) begin
|
||||
t_tlast <= 1'b1;
|
||||
end else begin
|
||||
t_tlast <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
r_cnt <= 0;
|
||||
end else if ( cstate == IDLE ) begin
|
||||
r_cnt <= 0;
|
||||
end else if ( r_tvalid ) begin
|
||||
r_cnt <= r_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
recv_data[0] <= 0;
|
||||
recv_data[1] <= 0;
|
||||
recv_data[2] <= 0;
|
||||
recv_data[3] <= 0;
|
||||
recv_data_en <= 1'b0;
|
||||
end else if ( r_tvalid ) begin
|
||||
recv_data[r_cnt] <= r_tdata;
|
||||
recv_data_en <= r_tlast;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
assign drdy = (cnv_drdy_r[3:2]==2'b10)? 1'b1:1'b0;
|
||||
assign upload_round = drdy;
|
||||
|
||||
//send_data_array
|
||||
generate
|
||||
for(i=0;i<4;i=i+1) begin : mapping
|
||||
assign send_data[i] = send_data_array[8*i+7 : 8*i];
|
||||
assign recv_data_array[8*i+7 : 8*i] = recv_data[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,193 @@
|
||||
`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
|
||||
@@ -0,0 +1,154 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module ads1299_mod#
|
||||
(
|
||||
parameter DATA_WIDTH = 8 ,
|
||||
parameter WIRE_DELAY = 11
|
||||
)
|
||||
(
|
||||
input cs ,
|
||||
input sclk ,
|
||||
input mosi ,
|
||||
output miso ,
|
||||
output reg drdy ,
|
||||
input start
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// localparam definition
|
||||
//*****************************************************************************
|
||||
localparam T_CLK = 31250 ; //ns
|
||||
|
||||
localparam RDATAC = 8'h08 ;
|
||||
localparam SDATAC = 8'h11 ;
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg clk ;
|
||||
reg rst_n ;
|
||||
|
||||
reg [ 8 - 1:0] serial_in ;
|
||||
reg [ 8 - 1:0] rx_cnt ;
|
||||
reg [ 8 - 1:0] rx_data ;
|
||||
|
||||
reg [ 8 - 1:0] tx_cnt ;
|
||||
reg [ 8 - 1:0] reg_data ;
|
||||
reg [ 8 - 1:0] cnv_data ;
|
||||
|
||||
reg [ 8 - 1:0] start_t_cnt ;
|
||||
reg cnv_en ;
|
||||
|
||||
reg [ 8 - 1:0] r_cnt ;
|
||||
|
||||
//*****************************************************************************
|
||||
always #( T_CLK/2.0 ) clk = !clk;
|
||||
|
||||
initial begin
|
||||
Initial();
|
||||
|
||||
#100 rst_n = 1;
|
||||
|
||||
while(1) begin
|
||||
@ ( posedge cnv_en );
|
||||
while ( cnv_en ) begin
|
||||
@ ( posedge clk );
|
||||
drdy <= cnv_en? 1'b0:1'b1;
|
||||
@ ( negedge sclk );
|
||||
drdy <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
initial begin
|
||||
clk <= 1'b0 ;
|
||||
rst_n <= 1'b0 ;
|
||||
|
||||
drdy <= 1'b1;
|
||||
end
|
||||
|
||||
//RX
|
||||
always @ ( negedge sclk or negedge rst_n or posedge cs ) begin
|
||||
if( !rst_n || cs )
|
||||
rx_cnt <= 0;
|
||||
else if ( rx_cnt != DATA_WIDTH )
|
||||
rx_cnt <= rx_cnt + 1'b1;
|
||||
else
|
||||
rx_cnt <= 1;
|
||||
end
|
||||
|
||||
always @ ( negedge sclk or negedge rst_n or negedge cs ) begin
|
||||
if( !rst_n || cs )
|
||||
serial_in <= 0;
|
||||
else
|
||||
serial_in <= {serial_in[6:0], mosi};
|
||||
end
|
||||
|
||||
always @ ( rx_cnt ) begin
|
||||
if( rx_cnt == 8 )
|
||||
rx_data <= serial_in;
|
||||
end
|
||||
|
||||
//data
|
||||
always@( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
start_t_cnt <= 0;
|
||||
else if ( start ) begin
|
||||
if ( start_t_cnt != 3 )
|
||||
start_t_cnt <= start_t_cnt + 1'b1;
|
||||
end else
|
||||
start_t_cnt <= 0;
|
||||
end
|
||||
|
||||
always@( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
cnv_en <= 1'b0;
|
||||
else if ( start_t_cnt == 3 )
|
||||
cnv_en <= 1'b1;
|
||||
else
|
||||
cnv_en <= 1'b0;
|
||||
end
|
||||
|
||||
always@( posedge sclk or negedge rst_n or posedge cs ) begin
|
||||
if ( !rst_n )
|
||||
r_cnt <= 0;
|
||||
else if ( cs )
|
||||
r_cnt <= 0;
|
||||
else
|
||||
r_cnt <= r_cnt + 1'b1;
|
||||
end
|
||||
|
||||
always@( posedge sclk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
cnv_data <= 0;
|
||||
end else if ( cnv_en && r_cnt[2:0] == 3'd0 && !cs ) begin
|
||||
cnv_data <= cnv_data + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( negedge cs or negedge rst_n or tx_cnt ) begin
|
||||
if ( !rst_n )
|
||||
reg_data <= 8'h55;
|
||||
else if ( tx_cnt == 7 )
|
||||
reg_data <= reg_data + 1'b1;
|
||||
end
|
||||
|
||||
//TX
|
||||
always @ ( posedge sclk or negedge rst_n or posedge cs ) begin
|
||||
if( !rst_n || cs )
|
||||
tx_cnt <= DATA_WIDTH;
|
||||
else if ( tx_cnt != 0 )
|
||||
tx_cnt <= tx_cnt - 1'b1;
|
||||
else
|
||||
tx_cnt <= DATA_WIDTH-1;
|
||||
end
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
assign #17 miso = (tx_cnt == DATA_WIDTH)? 1'b0:( cnv_en? cnv_data[tx_cnt]:reg_data[tx_cnt] );
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module ads1299_spi#
|
||||
(
|
||||
parameter CLK_PERIOD = 10 ,
|
||||
parameter CLK_DIV = 2 , // max: 255
|
||||
parameter DATA_WIDTH = 8 , // max: 255
|
||||
parameter OUTPUT_EDGE = 1 ,
|
||||
parameter SAMPLE_EDGE = 0 ,
|
||||
parameter NO_OF_SLAVES = 1
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst_n ,
|
||||
|
||||
input [ 8-1:0] t_cs_n ,
|
||||
input [ DATA_WIDTH-1:0] t_tdata ,
|
||||
input t_tlast ,
|
||||
output reg t_tready ,
|
||||
input t_tvalid ,
|
||||
|
||||
output reg [ DATA_WIDTH-1:0] r_tdata ,
|
||||
output reg r_tlast ,
|
||||
output reg r_tvalid ,
|
||||
|
||||
output [NO_OF_SLAVES-1:0] cs ,
|
||||
output sclk ,
|
||||
output mosi ,
|
||||
input miso
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// localparam definition
|
||||
//*****************************************************************************
|
||||
localparam CNT_POS = 0 ;
|
||||
localparam CNT_NEG = CLK_DIV/2 ;
|
||||
|
||||
localparam IDLE = 4'd0 ;
|
||||
localparam TRANS_ST = 4'd1 ;
|
||||
localparam END_ST = 4'd2 ;
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg [ 4-1:0] cstate ;
|
||||
reg [ 4-1:0] nstate ;
|
||||
|
||||
reg [DATA_WIDTH-1:0] tx_data ;
|
||||
reg [DATA_WIDTH-1:0] rx_data ;
|
||||
reg clk_en ;
|
||||
reg [ 9-1:0] cnt ;
|
||||
reg sck_pos ;
|
||||
reg sck_neg ;
|
||||
reg [ 8-1:0] trans_cnt ;
|
||||
|
||||
reg [ 8-1:0] slv_n ;
|
||||
reg [NO_OF_SLAVES-1:0] cs_r ;
|
||||
reg sclk_r ;
|
||||
|
||||
reg [NO_OF_SLAVES-1:0] cs_hold ;
|
||||
|
||||
//*****************************************************************************
|
||||
always@( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) cstate <= IDLE;
|
||||
else cstate <= nstate;
|
||||
end
|
||||
|
||||
always@( * ) begin
|
||||
case ( cstate )
|
||||
IDLE:
|
||||
if ( t_tvalid )
|
||||
nstate <= TRANS_ST;
|
||||
else
|
||||
nstate <= IDLE;
|
||||
TRANS_ST:
|
||||
if( (trans_cnt == 0) && sck_neg )
|
||||
nstate <= END_ST;
|
||||
else
|
||||
nstate <= TRANS_ST;
|
||||
END_ST:
|
||||
nstate <= IDLE;
|
||||
default:
|
||||
nstate <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
t_tready <= 1'b0;
|
||||
else if ( nstate == IDLE )
|
||||
t_tready <= 1'b1;
|
||||
else if ( cstate == IDLE && nstate == IDLE )
|
||||
t_tready <= 1'b1;
|
||||
else
|
||||
t_tready <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
slv_n <= 0;
|
||||
end else if ( cstate == IDLE || nstate == IDLE ) begin
|
||||
slv_n <= t_cs_n;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
cs_hold <= 0;
|
||||
else if ( t_tvalid && t_tready && t_tlast )
|
||||
cs_hold[slv_n] <= 1'b0;
|
||||
else if ( t_tvalid && t_tready )
|
||||
cs_hold[slv_n] <= 1'b1;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
cs_r <= {NO_OF_SLAVES{1'b1}};
|
||||
else if ( cstate == IDLE || nstate == IDLE )
|
||||
cs_r[slv_n] <= ~cs_hold[slv_n];
|
||||
else
|
||||
cs_r[slv_n] <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
tx_data <= 0;
|
||||
end else if ( t_tready && t_tvalid ) begin
|
||||
tx_data <= t_tdata;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
clk_en <= 0;
|
||||
else if ( ((cstate == IDLE) && (nstate == TRANS_ST)) || ((cstate == TRANS_ST) && (nstate != END_ST)) )
|
||||
clk_en <= 1'b1;
|
||||
else if ( nstate == END_ST )
|
||||
clk_en <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
cnt <= 0;
|
||||
else if ( !clk_en )
|
||||
cnt <= 0;
|
||||
else if ( cnt == CLK_DIV-1 )
|
||||
cnt <= 0;
|
||||
else
|
||||
cnt <= cnt + 1;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
sck_pos <= 0;
|
||||
else if ( clk_en && (cnt == CNT_POS) )
|
||||
sck_pos <= 1;
|
||||
else
|
||||
sck_pos <= 0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
sck_neg <= 0;
|
||||
else if ( clk_en && (cnt == CNT_NEG) )
|
||||
sck_neg <= 1;
|
||||
else
|
||||
sck_neg <= 0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
sclk_r <= 0;
|
||||
else if ( sck_pos )
|
||||
sclk_r <= 1'b1;
|
||||
else if ( sck_neg )
|
||||
sclk_r <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
trans_cnt <= DATA_WIDTH;
|
||||
else if ( cstate == IDLE )
|
||||
trans_cnt <= DATA_WIDTH;
|
||||
else if ( sck_pos && (trans_cnt != 0) )
|
||||
// else if ( sck_neg && (trans_cnt != 0) )
|
||||
trans_cnt <= trans_cnt - 1'b1;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
rx_data <= 0;
|
||||
// else if ( sck_pos )
|
||||
else if ( sck_neg )
|
||||
rx_data[trans_cnt] <= miso;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
r_tvalid <= 1'b0;
|
||||
r_tdata <= 0;
|
||||
end else if ( (cstate == END_ST)&&(nstate == IDLE) ) begin
|
||||
r_tvalid <= 1'b1;
|
||||
r_tdata <= rx_data;
|
||||
end else begin
|
||||
r_tvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
r_tlast <= 1'b0;
|
||||
end else if ( (cstate == END_ST)&&(nstate == IDLE) ) begin
|
||||
r_tlast <= ~cs_hold[slv_n];
|
||||
end else begin
|
||||
r_tlast <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
assign cs = cs_r;
|
||||
assign sclk = sclk_r;
|
||||
assign mosi = (trans_cnt==DATA_WIDTH)? 1'b0:tx_data[trans_cnt];
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,262 @@
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module ads1299_spi#
|
||||
(
|
||||
parameter CLK_PERIOD = 10 ,
|
||||
parameter CLK_DIV = 3 , // max: 255
|
||||
parameter DATA_WIDTH = 8 , // max: 255
|
||||
parameter NO_OF_SLAVES = 1
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst_n ,
|
||||
|
||||
input [ 8-1:0] t_cs_n ,
|
||||
input [ DATA_WIDTH-1:0] t_tdata ,
|
||||
input t_tlast ,
|
||||
output reg t_tready ,
|
||||
input t_tvalid ,
|
||||
|
||||
output reg [ DATA_WIDTH-1:0] r_tdata ,
|
||||
output reg r_tlast ,
|
||||
output reg r_tvalid ,
|
||||
|
||||
output [NO_OF_SLAVES-1:0] cs ,
|
||||
output sclk ,
|
||||
output mosi ,
|
||||
input miso
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// localparam definition
|
||||
//*****************************************************************************
|
||||
localparam CNT_POS = CLK_DIV-1 ;
|
||||
localparam CNT_NEG = CLK_DIV*2-1 ;
|
||||
|
||||
localparam T_SCCS = 2000/CLK_PERIOD ;
|
||||
localparam T_SCH = 600/CLK_PERIOD ;
|
||||
|
||||
localparam IDLE = 4'd0;
|
||||
localparam TRANS_ST = 4'd1;
|
||||
localparam SCCS_ST = 4'd2;
|
||||
localparam CSH_ST = 4'd3;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg [ 4-1:0] cstate ;
|
||||
reg [ 4-1:0] nstate ;
|
||||
|
||||
reg [DATA_WIDTH-1:0] tx_data ;
|
||||
reg [DATA_WIDTH-1:0] rx_data ;
|
||||
reg clk_en ;
|
||||
reg [ 9-1:0] cnt ;
|
||||
reg sck_pos ;
|
||||
reg sck_neg ;
|
||||
reg [ 8-1:0] trans_cnt ;
|
||||
|
||||
reg [ 8-1:0] slv_n ;
|
||||
reg [NO_OF_SLAVES-1:0] cs_r ;
|
||||
reg sclk_r ;
|
||||
|
||||
reg [NO_OF_SLAVES-1:0] cs_release ;
|
||||
|
||||
reg [ 8-1:0] t_sccs_cnt ;
|
||||
reg [ 8-1:0] t_sch_cnt ;
|
||||
|
||||
reg read_flag ;
|
||||
|
||||
//*****************************************************************************
|
||||
always@( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) cstate <= IDLE;
|
||||
else cstate <= nstate;
|
||||
end
|
||||
|
||||
always@( * ) begin
|
||||
case ( cstate )
|
||||
IDLE:
|
||||
if ( t_tvalid )
|
||||
nstate <= TRANS_ST;
|
||||
else
|
||||
nstate <= IDLE;
|
||||
TRANS_ST:
|
||||
if( (trans_cnt == 0) && sck_neg )
|
||||
nstate <= (cs_release[slv_n])? SCCS_ST : IDLE;
|
||||
else
|
||||
nstate <= TRANS_ST;
|
||||
SCCS_ST:
|
||||
if ( t_sccs_cnt == T_SCCS - 1 )
|
||||
nstate <= CSH_ST;
|
||||
else
|
||||
nstate <= SCCS_ST;
|
||||
CSH_ST:
|
||||
if ( t_sch_cnt == T_SCH - 1 )
|
||||
nstate <= IDLE;
|
||||
else
|
||||
nstate <= CSH_ST;
|
||||
default:
|
||||
nstate <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
t_tready <= 1'b0;
|
||||
else if ( nstate == IDLE )
|
||||
t_tready <= 1'b1;
|
||||
else if ( cstate == IDLE && nstate == IDLE )
|
||||
t_tready <= 1'b1;
|
||||
else
|
||||
t_tready <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
slv_n <= 0;
|
||||
end else if ( cstate == IDLE || nstate == IDLE ) begin
|
||||
slv_n <= t_cs_n;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
cs_release <= 1'b0;
|
||||
else if ( t_tvalid && t_tready && t_tlast )
|
||||
cs_release[slv_n] <= 1'b1;
|
||||
else if ( t_tvalid && t_tready )
|
||||
cs_release[slv_n] <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
cs_r <= {NO_OF_SLAVES{1'b1}};
|
||||
else if ( cstate == TRANS_ST )
|
||||
cs_r[slv_n] <= 1'b0;
|
||||
else if ( nstate == CSH_ST )
|
||||
cs_r[slv_n] <= cs_release[slv_n];
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
tx_data <= 0;
|
||||
end else if ( t_tready && t_tvalid ) begin
|
||||
tx_data <= t_tdata;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
clk_en <= 0;
|
||||
else if ( ((cstate == IDLE) && (nstate == TRANS_ST)) || ((cstate == TRANS_ST) && (nstate != SCCS_ST)) )
|
||||
clk_en <= 1'b1;
|
||||
else if ( nstate == SCCS_ST || nstate == IDLE )
|
||||
clk_en <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
cnt <= 0;
|
||||
else if ( !clk_en )
|
||||
cnt <= 0;
|
||||
else if ( cnt == CLK_DIV*2-1 )
|
||||
cnt <= 0;
|
||||
else
|
||||
cnt <= cnt + 1;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
sck_pos <= 0;
|
||||
else if ( clk_en && (cnt == CNT_POS) )
|
||||
sck_pos <= 1;
|
||||
else
|
||||
sck_pos <= 0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
sck_neg <= 0;
|
||||
else if ( clk_en && (cnt == CNT_NEG) )
|
||||
sck_neg <= 1;
|
||||
else
|
||||
sck_neg <= 0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
sclk_r <= 0;
|
||||
else if ( sck_pos && nstate == TRANS_ST )
|
||||
sclk_r <= 1'b1;
|
||||
else if ( sck_neg )
|
||||
sclk_r <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
trans_cnt <= DATA_WIDTH;
|
||||
else if ( cstate == IDLE )
|
||||
trans_cnt <= DATA_WIDTH;
|
||||
else if ( sck_pos && (trans_cnt != 0) )
|
||||
trans_cnt <= trans_cnt - 1'b1;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
rx_data <= 0;
|
||||
else if ( sck_neg )
|
||||
rx_data[trans_cnt] <= miso;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
read_flag <= 1'b0;
|
||||
else if ( cstate == TRANS_ST && nstate != TRANS_ST )
|
||||
read_flag <= 1'b1;
|
||||
else
|
||||
read_flag <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
r_tvalid <= 1'b0;
|
||||
r_tdata <= 0;
|
||||
r_tlast <= 1'b0;
|
||||
end else if ( read_flag ) begin
|
||||
r_tvalid <= 1'b1;
|
||||
r_tdata <= rx_data;
|
||||
r_tlast <= cs_release[slv_n];
|
||||
end else begin
|
||||
r_tvalid <= 1'b0;
|
||||
r_tlast <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
t_sccs_cnt <= 0;
|
||||
end else if ( cstate != SCCS_ST ) begin
|
||||
t_sccs_cnt <= 0;
|
||||
end else begin
|
||||
t_sccs_cnt <= t_sccs_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
t_sch_cnt <= 0;
|
||||
end else if ( cstate != CSH_ST ) begin
|
||||
t_sch_cnt <= 0;
|
||||
end else begin
|
||||
t_sch_cnt <= t_sch_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
assign cs = cs_r;
|
||||
assign sclk = sclk_r;
|
||||
assign mosi = (trans_cnt==DATA_WIDTH)? 1'b0:tx_data[trans_cnt];
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,116 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module ads1299_spi_tb();
|
||||
|
||||
//*****************************************************************************
|
||||
// Parameter definition
|
||||
//*****************************************************************************
|
||||
parameter T_CLK = 20; //ns
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg clk ;
|
||||
reg rst_n ;
|
||||
|
||||
reg trans ;
|
||||
|
||||
wire rdy ;
|
||||
reg start ;
|
||||
reg [32 - 1:0] din ;
|
||||
wire done ;
|
||||
wire [32 - 1:0] dout ;
|
||||
|
||||
wire cs ;
|
||||
wire sclk ;
|
||||
wire mosi ;
|
||||
wire miso ;
|
||||
|
||||
reg [32 - 1:0] data ;
|
||||
reg [ 8 - 1:0] cnt ;
|
||||
|
||||
//GSR GSR(.GSRI(1'b1));
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
always #( T_CLK/2.0 ) clk = !clk;
|
||||
|
||||
initial begin
|
||||
Initial();
|
||||
#100 rst_n = 0;
|
||||
#100 rst_n = 1;
|
||||
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
trans <= 1'b0 ;
|
||||
else if (cs) begin
|
||||
#200 trans <= 1'b1;
|
||||
#20 trans <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
start <= 1'b0;
|
||||
din <= 0;
|
||||
data <= 0;
|
||||
end else if ( trans ) begin
|
||||
start <= 1'b1;
|
||||
din <= 32'hAAAA5555;//$random;
|
||||
data <= 32'hCCCCAAA5;//$random;
|
||||
end else
|
||||
start <= 1'b0;
|
||||
end
|
||||
|
||||
always @ ( negedge sclk or negedge rst_n or posedge cs ) begin
|
||||
if( !rst_n )
|
||||
cnt <= 8'd31;
|
||||
else if( cs )
|
||||
cnt <= 8'd31;
|
||||
else if ( cnt != 0 )
|
||||
cnt <= cnt - 1'b1;
|
||||
end
|
||||
|
||||
assign miso = data[cnt];
|
||||
|
||||
//*****************************************************************************
|
||||
// Task
|
||||
//*****************************************************************************
|
||||
task Initial;
|
||||
begin
|
||||
clk <= 1'b0 ;
|
||||
rst_n <= 1'b0 ;
|
||||
end
|
||||
endtask
|
||||
|
||||
//*****************************************************************************
|
||||
// Instantiation
|
||||
//*****************************************************************************
|
||||
ads1299_spi#
|
||||
(
|
||||
.CLK_PERIOD ( 50 ),
|
||||
.CLK_DIV ( 2 ),
|
||||
.DATA_WIDTH ( 32 )
|
||||
)
|
||||
DUT
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.rdy ( rdy ),
|
||||
.start ( start ),
|
||||
.din ( din ),
|
||||
.done ( done ),
|
||||
.dout ( dout ),
|
||||
|
||||
.cs ( cs ),
|
||||
.sclk ( sclk ),
|
||||
.mosi ( mosi ),
|
||||
.miso ( miso )
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,151 @@
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module eeg_config#
|
||||
(
|
||||
parameter SPIS_QTY = 4 ,
|
||||
parameter SPI_DATA_WIDTH = 8
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst_n ,
|
||||
|
||||
input [13-1:0] bram_addr ,
|
||||
input bram_clk ,
|
||||
input [32-1:0] bram_din ,
|
||||
output reg [32-1:0] bram_dout ,
|
||||
input bram_en ,
|
||||
input bram_rst ,
|
||||
input [ 4-1:0] bram_we ,
|
||||
|
||||
//------------------------------------------ eeg
|
||||
output [32-1:0] eeg_er ,
|
||||
output [32-1:0] eeg_cr ,
|
||||
input [32-1:0] eeg_sr ,
|
||||
output [32*SPIS_QTY-1:0] eeg_tr_array ,
|
||||
input [32*SPIS_QTY-1:0] eeg_rr_array ,
|
||||
|
||||
output reg eeg_sr_r_evt
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// localparam definition
|
||||
//*****************************************************************************
|
||||
localparam BRAM_ADDR_TEST_RO = 13'h0000;
|
||||
localparam BRAM_ADDR_TEST_RW = 13'h0004;
|
||||
|
||||
localparam BRAM_ADDR_EEG_ER = 13'h0040;
|
||||
localparam BRAM_ADDR_EEG_CR = 13'h0044;
|
||||
localparam BRAM_ADDR_EEG_SR = 13'h0048;
|
||||
localparam BRAM_ADDR_EEG_TR = 13'h0100;
|
||||
localparam BRAM_ADDR_EEG_RR = 13'h0200;
|
||||
|
||||
localparam BRAM_ADDR_EEG_TR_MASK = 13'h1F00;
|
||||
localparam BRAM_ADDR_EEG_RR_MASK = 13'h1F00;
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg [32-1:0] test_data ;
|
||||
|
||||
wire bram_wr_valid ;
|
||||
wire bram_rd_valid ;
|
||||
|
||||
reg [32-1:0] eeg_er_r ;
|
||||
reg [32-1:0] eeg_cr_r ;
|
||||
reg [32-1:0] eeg_tr_r[SPIS_QTY-1:0] ;
|
||||
wire [32-1:0] eeg_rr_r[SPIS_QTY-1:0] ;
|
||||
|
||||
integer n;
|
||||
|
||||
genvar i;
|
||||
|
||||
//*****************************************************************************
|
||||
// Procedural blocks
|
||||
//*****************************************************************************
|
||||
|
||||
//write bram/Set config
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
test_data <= 0;
|
||||
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_TEST_RW ) )
|
||||
test_data <= bram_din;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
eeg_er_r <= 0;
|
||||
end else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_EEG_ER ) ) begin
|
||||
eeg_er_r <= bram_din;
|
||||
end else begin
|
||||
eeg_er_r <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
eeg_cr_r <= 0;
|
||||
end else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_EEG_CR ) ) begin
|
||||
eeg_cr_r <= bram_din;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
n = 0;
|
||||
while(n<SPIS_QTY) begin
|
||||
eeg_tr_r[n] <= 0;
|
||||
n = n + 1;
|
||||
end
|
||||
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_EEG_TR_MASK) == BRAM_ADDR_EEG_TR ) )
|
||||
eeg_tr_r[bram_addr[7:2]] <= bram_din;
|
||||
end
|
||||
|
||||
//read bram/Get config
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) begin
|
||||
bram_dout <= 0;
|
||||
end else if ( bram_rd_valid ) begin
|
||||
|
||||
if ( bram_addr == BRAM_ADDR_TEST_RO )
|
||||
bram_dout <= 32'h12345678;
|
||||
|
||||
if ( bram_addr == BRAM_ADDR_TEST_RW )
|
||||
bram_dout <= test_data;
|
||||
|
||||
if ( bram_addr == BRAM_ADDR_EEG_SR ) begin
|
||||
bram_dout <= eeg_sr;
|
||||
eeg_sr_r_evt <= 1'b1;
|
||||
end
|
||||
|
||||
if ( (bram_addr & BRAM_ADDR_EEG_RR_MASK) == BRAM_ADDR_EEG_RR )
|
||||
bram_dout <= eeg_rr_r[bram_addr[7:2]];
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n )
|
||||
eeg_sr_r_evt <= 1'b0;
|
||||
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_EEG_SR ) )
|
||||
eeg_sr_r_evt <= 1'b1;
|
||||
else
|
||||
eeg_sr_r_evt <= 1'b0;
|
||||
end
|
||||
|
||||
//*****************************************************************************
|
||||
// Continuous assignments
|
||||
//*****************************************************************************
|
||||
assign bram_wr_valid = bram_en && (bram_we == 4'hF);
|
||||
assign bram_rd_valid = bram_en && (bram_we == 4'h0);
|
||||
|
||||
generate
|
||||
for(i=0;i<SPIS_QTY;i=i+1) begin : mapping
|
||||
assign eeg_tr_array[32*i+31 : 32*i] = eeg_tr_r[i];
|
||||
assign eeg_rr_r[i] = eeg_rr_array[32*i+31 : 32*i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign eeg_er = eeg_er_r;
|
||||
assign eeg_cr = eeg_cr_r;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,272 @@
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module eeg_top#
|
||||
(
|
||||
parameter CLK_PERIOD = 10 ,
|
||||
|
||||
parameter CHIPSET_QTY = 8 ,
|
||||
parameter CHIPSET_CH_QTY = 8 ,
|
||||
parameter SPIS_QTY = 4 ,
|
||||
parameter SPI_SLAVE_QTY = 2 ,
|
||||
|
||||
parameter SPI_CLK_DIV = 3 ,
|
||||
parameter SPI_DATA_WIDTH = 8 ,
|
||||
parameter SPI_TRANS_PERIOD = 2000 //Unit: ns
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst_n ,
|
||||
|
||||
input [13-1:0] bram_addr ,
|
||||
input bram_clk ,
|
||||
input [32-1:0] bram_din ,
|
||||
output [32-1:0] bram_dout ,
|
||||
input bram_en ,
|
||||
input bram_rst ,
|
||||
input [ 4-1:0] bram_we ,
|
||||
|
||||
output interrupt ,
|
||||
|
||||
output [32-1:0] axis_record_tdata ,
|
||||
output axis_record_tlast ,
|
||||
input axis_record_tready ,
|
||||
output axis_record_tvalid ,
|
||||
|
||||
output [CHIPSET_QTY-1:0] cs ,
|
||||
output [ SPIS_QTY-1:0] sclk ,
|
||||
output [ SPIS_QTY-1:0] mosi ,
|
||||
input [ SPIS_QTY-1:0] miso ,
|
||||
input [ SPIS_QTY-1:0] drdy ,
|
||||
output start ,
|
||||
|
||||
output [ 4-1:0] debug_sig
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// localparam definition
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
wire [32-1:0] eeg_er ;
|
||||
wire [32-1:0] eeg_cr ;
|
||||
wire [32-1:0] eeg_sr ;
|
||||
wire [32*SPIS_QTY-1:0] eeg_tr_array ;
|
||||
wire [32*SPIS_QTY-1:0] eeg_rr_array ;
|
||||
wire eeg_sr_r_evt ;
|
||||
|
||||
wire [SPI_SLAVE_QTY-1:0] cs_w[SPIS_QTY-1:0] ;
|
||||
|
||||
wire send_enable[SPIS_QTY-1:0] ;
|
||||
wire [ 8-1:0] send_cs_n[SPIS_QTY-1:0] ;
|
||||
wire [ 8-1:0] send_length[SPIS_QTY-1:0] ;
|
||||
wire [32-1:0] send_data_array[SPIS_QTY-1:0] ;
|
||||
wire [32-1:0] recv_data_array[SPIS_QTY-1:0] ;
|
||||
wire recv_data_en_array[SPIS_QTY-1:0];
|
||||
|
||||
wire [ 8-1:0] t_cs_n[SPIS_QTY-1:0] ;
|
||||
wire [ 8-1:0] t_tdata[SPIS_QTY-1:0] ;
|
||||
wire t_tlast[SPIS_QTY-1:0] ;
|
||||
wire t_tready[SPIS_QTY-1:0] ;
|
||||
wire t_tvalid[SPIS_QTY-1:0] ;
|
||||
|
||||
wire [ 8-1:0] r_tdata[SPIS_QTY-1:0] ;
|
||||
wire r_tlast[SPIS_QTY-1:0] ;
|
||||
wire r_tvalid[SPIS_QTY-1:0] ;
|
||||
|
||||
wire cnv_start[SPIS_QTY-1:0] ;
|
||||
wire cnv_drdy[SPIS_QTY-1:0] ;
|
||||
wire upload_round[SPIS_QTY-1:0] ;
|
||||
|
||||
//------------------------------------------ record stream rx
|
||||
wire [32-1:0] cnv_res_tdata[SPIS_QTY-1:0] ;
|
||||
wire cnv_res_tlast[SPIS_QTY-1:0] ;
|
||||
wire cnv_res_tready[SPIS_QTY-1:0] ;
|
||||
wire cnv_res_tvalid[SPIS_QTY-1:0] ;
|
||||
|
||||
wire [32*SPIS_QTY-1:0] cnv_res_tdata_array ;
|
||||
wire [ SPIS_QTY-1:0] cnv_res_tlast_array ;
|
||||
wire [ SPIS_QTY-1:0] cnv_res_tready_array ;
|
||||
wire [ SPIS_QTY-1:0] cnv_res_tvalid_array ;
|
||||
|
||||
wire record_enable ;
|
||||
|
||||
genvar i;
|
||||
|
||||
//*****************************************************************************
|
||||
// Instantiation
|
||||
//*****************************************************************************
|
||||
eeg_config#
|
||||
(
|
||||
.SPIS_QTY ( 4 ),
|
||||
.SPI_DATA_WIDTH ( 8 )
|
||||
)
|
||||
u_eeg_config
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.bram_addr ( bram_addr ),
|
||||
.bram_clk ( bram_clk ),
|
||||
.bram_din ( bram_din ),
|
||||
.bram_dout ( bram_dout ),
|
||||
.bram_en ( bram_en ),
|
||||
.bram_rst ( bram_rst ),
|
||||
.bram_we ( bram_we ),
|
||||
|
||||
//eeg
|
||||
.eeg_er ( eeg_er ),
|
||||
.eeg_cr ( eeg_cr ),
|
||||
.eeg_sr ( eeg_sr ),
|
||||
.eeg_tr_array ( eeg_tr_array ),
|
||||
.eeg_rr_array ( eeg_rr_array ),
|
||||
|
||||
.eeg_sr_r_evt ( eeg_sr_r_evt )
|
||||
);
|
||||
|
||||
generate
|
||||
for(i=0;i<SPIS_QTY;i=i+1) begin : transmit_arrange
|
||||
ads1299_arrange#
|
||||
(
|
||||
.CLK_PERIOD ( 10 ),
|
||||
.SPI_DATA_WIDTH ( 8 ),
|
||||
.SPI_TRANS_PERIOD ( SPI_TRANS_PERIOD )
|
||||
)
|
||||
u_ads1299_arrange
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.send_cs_n ( send_cs_n[i] ),
|
||||
.send_enable ( send_enable[i] ),
|
||||
.send_length ( send_length[i] ),
|
||||
.send_data_array ( send_data_array[i] ),
|
||||
.recv_data_en ( recv_data_en_array[i] ),
|
||||
.recv_data_array ( recv_data_array[i] ),
|
||||
|
||||
.t_cs_n ( t_cs_n[i] ),
|
||||
.t_tdata ( t_tdata[i] ),
|
||||
.t_tlast ( t_tlast[i] ),
|
||||
.t_tready ( t_tready[i] ),
|
||||
.t_tvalid ( t_tvalid[i] ),
|
||||
|
||||
.r_tdata ( r_tdata[i] ),
|
||||
.r_tlast ( r_tlast[i] ),
|
||||
.r_tvalid ( r_tvalid[i] ),
|
||||
|
||||
.rdatac_enable ( record_enable ),
|
||||
.cnv_start ( cnv_start[i] ),
|
||||
.cnv_drdy ( cnv_drdy[0] ),
|
||||
.upload_round ( upload_round[i] )
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i=0;i<SPIS_QTY;i=i+1) begin : trans_if
|
||||
ads1299_if#
|
||||
(
|
||||
.SPI_CLK_DIV ( SPI_CLK_DIV ),
|
||||
.SPI_DATA_WIDTH ( SPI_DATA_WIDTH ),
|
||||
.SPI_SLAVE_QTY ( SPI_SLAVE_QTY )
|
||||
)
|
||||
u_ads1299_if
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.upload_enable ( record_enable ),
|
||||
.upload_round ( upload_round[i] ),
|
||||
|
||||
//------------------------------------------ spi direct communication
|
||||
.t_cs_n ( t_cs_n[i] ),
|
||||
.t_tdata ( t_tdata[i] ),
|
||||
.t_tlast ( t_tlast[i] ),
|
||||
.t_tready ( t_tready[i] ),
|
||||
.t_tvalid ( t_tvalid[i] ),
|
||||
|
||||
.r_tdata ( r_tdata[i] ),
|
||||
.r_tlast ( r_tlast[i] ),
|
||||
.r_tvalid ( r_tvalid[i] ),
|
||||
|
||||
//------------------------------------------ record stream rx
|
||||
.cnv_res_tdata ( cnv_res_tdata[i] ),
|
||||
.cnv_res_tlast ( cnv_res_tlast[i] ),
|
||||
.cnv_res_tready ( cnv_res_tready[i] ),
|
||||
.cnv_res_tvalid ( cnv_res_tvalid[i] ),
|
||||
|
||||
//------------------------------------------ device spi
|
||||
.cs ( cs_w[i] ),
|
||||
.sclk ( sclk[i] ),
|
||||
.mosi ( mosi[i] ),
|
||||
.miso ( miso[i] )
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
eeg_upload#
|
||||
(
|
||||
.CLK_PERIOD ( CLK_PERIOD ),
|
||||
.CHIPSET_QTY ( SPIS_QTY ),
|
||||
.CH_OF_CHIPSET ( CHIPSET_CH_QTY*SPI_SLAVE_QTY )
|
||||
)
|
||||
u_eeg_upload
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.trans_round ( upload_round[0] ),
|
||||
|
||||
.cnv_res_tdata_array ( cnv_res_tdata_array ),
|
||||
.cnv_res_tlast_array ( cnv_res_tlast_array ),
|
||||
.cnv_res_tready_array ( cnv_res_tready_array ),
|
||||
.cnv_res_tvalid_array ( cnv_res_tvalid_array ),
|
||||
|
||||
.axi_str_rxd_tdata ( axis_record_tdata ),
|
||||
.axi_str_rxd_tlast ( axis_record_tlast ),
|
||||
.axi_str_rxd_tready ( axis_record_tready ),
|
||||
.axi_str_rxd_tvalid ( axis_record_tvalid )
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// Procedural blocks
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
assign record_enable = eeg_cr[31];
|
||||
|
||||
assign start = cnv_start[0];
|
||||
|
||||
generate
|
||||
for(i=0;i<SPIS_QTY;i=i+1) begin : mapping
|
||||
assign send_enable[i] = eeg_er[i];
|
||||
|
||||
assign send_cs_n[i] = {6'd0, eeg_cr[4*i+1:4*i+0]};
|
||||
assign send_length[i] = {6'd0, eeg_cr[4*i+3:4*i+2]};
|
||||
|
||||
assign send_data_array[i] = eeg_tr_array[32*i+31:32*i];
|
||||
assign eeg_rr_array[32*i+31:32*i] = recv_data_array[i];
|
||||
|
||||
assign cs[SPI_SLAVE_QTY*(i+1)-1 : SPI_SLAVE_QTY*i] = cs_w[i];
|
||||
assign cnv_drdy[i] = drdy[i];
|
||||
|
||||
assign cnv_res_tdata_array[32*i+31 : 32*i] = cnv_res_tdata[i];
|
||||
assign cnv_res_tlast_array[i] = cnv_res_tlast[i];
|
||||
assign cnv_res_tvalid_array[i] = cnv_res_tvalid[i];
|
||||
assign cnv_res_tready[i] = cnv_res_tready_array[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign interrupt = 1'b0;
|
||||
|
||||
assign debug_sig[0] = record_enable;
|
||||
assign debug_sig[1] = 1'b0;
|
||||
assign debug_sig[2] = 1'b0;
|
||||
assign debug_sig[3] = 1'b0;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,286 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module eeg_top_tb();
|
||||
|
||||
//*****************************************************************************
|
||||
// Parameter definition
|
||||
//*****************************************************************************
|
||||
localparam T_CLK = 10; //ns
|
||||
|
||||
localparam SPIS_QTY = 4;
|
||||
localparam CHIPSET_QTY = 8;
|
||||
|
||||
localparam BRAM_ADDR_TEST_RO = 13'h0000;
|
||||
localparam BRAM_ADDR_TEST_RW = 13'h0004;
|
||||
|
||||
localparam BRAM_ADDR_EEG_ER = 13'h0040;
|
||||
localparam BRAM_ADDR_EEG_CR = 13'h0044;
|
||||
localparam BRAM_ADDR_EEG_SR = 13'h0048;
|
||||
localparam BRAM_ADDR_EEG_TR = 13'h0100;
|
||||
localparam BRAM_ADDR_EEG_RR = 13'h0200;
|
||||
|
||||
localparam BRAM_ADDR_EEG_TR_MASK = 13'h1F00;
|
||||
localparam BRAM_ADDR_EEG_RR_MASK = 13'h1F00;
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg clk ;
|
||||
reg rst_n ;
|
||||
|
||||
reg [13-1:0] bram_eeg_addr ;
|
||||
reg bram_eeg_clk ;
|
||||
reg [32-1:0] bram_eeg_din ;
|
||||
wire [32-1:0] bram_eeg_dout ;
|
||||
reg bram_eeg_en ;
|
||||
reg bram_eeg_rst ;
|
||||
reg [ 4-1:0] bram_eeg_we ;
|
||||
|
||||
wire interrupt ;
|
||||
|
||||
reg [32-1:0] trigger_tdata ;
|
||||
reg trigger_tvalid ;
|
||||
|
||||
reg [32-1:0] read_data ;
|
||||
|
||||
wire [32-1:0] axis_record_tdata ;
|
||||
wire axis_record_tlast ;
|
||||
reg axis_record_tready ;
|
||||
wire axis_record_tvalid ;
|
||||
|
||||
wire [CHIPSET_QTY-1:0] cs_w ;
|
||||
wire [ SPIS_QTY-1:0] sclk_w ;
|
||||
wire [ SPIS_QTY-1:0] mosi_w ;
|
||||
wire [ SPIS_QTY-1:0] miso_w ;
|
||||
wire [ SPIS_QTY-1:0] drdy_w ;
|
||||
wire start_w ;
|
||||
|
||||
wire [CHIPSET_QTY-1:0] cs ;
|
||||
wire [CHIPSET_QTY-1:0] sclk ;
|
||||
wire [CHIPSET_QTY-1:0] mosi ;
|
||||
wire [CHIPSET_QTY-1:0] miso ;
|
||||
wire [CHIPSET_QTY-1:0] drdy ;
|
||||
wire [CHIPSET_QTY-1:0] start ;
|
||||
|
||||
integer n;
|
||||
genvar i;
|
||||
|
||||
//*****************************************************************************
|
||||
// Instantiation
|
||||
//*****************************************************************************
|
||||
eeg_top#
|
||||
(
|
||||
.CLK_PERIOD ( T_CLK )
|
||||
)
|
||||
DUT
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.bram_addr ( bram_eeg_addr ),
|
||||
.bram_clk ( bram_eeg_clk ),
|
||||
.bram_din ( bram_eeg_din ),
|
||||
.bram_dout ( bram_eeg_dout ),
|
||||
.bram_en ( bram_eeg_en ),
|
||||
.bram_rst ( bram_eeg_rst ),
|
||||
.bram_we ( bram_eeg_we ),
|
||||
|
||||
.interrupt ( interrupt ),
|
||||
|
||||
.trigger_tdata ( trigger_tdata ),
|
||||
.trigger_tvalid ( trigger_tvalid ),
|
||||
|
||||
//------------------------------------------ FIFO: eeg output
|
||||
.axis_record_tdata ( axis_record_tdata ),
|
||||
.axis_record_tlast ( axis_record_tlast ),
|
||||
.axis_record_tready ( axis_record_tready ),
|
||||
.axis_record_tvalid ( axis_record_tvalid ),
|
||||
|
||||
//------------------------------------------ device spi
|
||||
.cs ( cs_w ),
|
||||
.sclk ( sclk_w ),
|
||||
.mosi ( mosi_w ),
|
||||
.miso ( miso_w ),
|
||||
.drdy ( drdy_w ),
|
||||
.start ( start_w )
|
||||
);
|
||||
|
||||
generate
|
||||
for(i=0; i<CHIPSET_QTY; i=i+1) begin : spi
|
||||
ads1299_mod u_ads1299_mod
|
||||
(
|
||||
.cs ( cs[i] ),
|
||||
.sclk ( sclk[i] ),
|
||||
.mosi ( mosi[i] ),
|
||||
.miso ( miso[i] ),
|
||||
.drdy ( drdy[i] ),
|
||||
.start ( start[i] )
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//*****************************************************************************
|
||||
always #( T_CLK/2.0 ) clk = !clk;
|
||||
|
||||
initial begin
|
||||
Initial();
|
||||
#100 rst_n = 0;
|
||||
#100 rst_n = 1;
|
||||
#100
|
||||
|
||||
/*
|
||||
//SDATAC
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h00, 32'h00000011);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h04, 32'h00000011);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h08, 32'h00000011);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h0C, 32'h00000011);
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_CR, {16'd0, 4'b0100, 4'b0100, 4'b0100, 4'b0100});
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_ER, 32'hF);
|
||||
#4_000
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_CR, {16'd0, 4'b0101, 4'b0101, 4'b0101, 4'b0101});
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_ER, 32'hF);
|
||||
#4_000
|
||||
|
||||
//READ ID
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h00, 32'h00010020);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h04, 32'h00020020);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h08, 32'h00030020);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h0C, 32'h00040020);
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_CR, {16'd0, 4'b1100, 4'b1100, 4'b1100, 4'b1100});
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_ER, 32'hF);
|
||||
#10_000
|
||||
read_bram_eeg(BRAM_ADDR_EEG_RR+4'h0, read_data);
|
||||
#100
|
||||
// $stop;
|
||||
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h00, 32'h00010020);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h04, 32'h00020020);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h08, 32'h00030020);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h0C, 32'h00040020);
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_CR, {16'd0, 4'b1101, 4'b1101, 4'b1101, 4'b1101});
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_ER, 32'hF);
|
||||
#10_000
|
||||
|
||||
//
|
||||
#7_000
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h00, 32'h00000010);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h04, 32'h00000010);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h08, 32'h00000010);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h0C, 32'h00000010);
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_CR, {16'd0, 4'b0100, 4'b0100, 4'b0100, 4'b0100});
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_ER, 32'hF);
|
||||
|
||||
#3_000
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h00, 32'h00000010);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h04, 32'h00000010);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h08, 32'h00000010);
|
||||
write_bram_eeg(BRAM_ADDR_EEG_TR + 8'h0C, 32'h00000010);
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_CR, {16'd0, 4'b0101, 4'b0101, 4'b0101, 4'b0101});
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_ER, 32'hF);
|
||||
*/
|
||||
|
||||
#3_000
|
||||
@ ( posedge clk );
|
||||
write_bram_eeg(BRAM_ADDR_EEG_CR, {1'b1, 15'd10, 16'd0});
|
||||
|
||||
// #40_000
|
||||
// @ ( posedge clk );
|
||||
// $stop;
|
||||
|
||||
end
|
||||
|
||||
//*****************************************************************************
|
||||
// Task
|
||||
//*****************************************************************************
|
||||
task Initial;
|
||||
begin
|
||||
clk <= 1'b0 ;
|
||||
rst_n <= 1'b0 ;
|
||||
|
||||
bram_eeg_addr <= 0 ;
|
||||
bram_eeg_clk <= 1'b0 ;
|
||||
bram_eeg_din <= 0 ;
|
||||
bram_eeg_en <= 1'b0 ;
|
||||
bram_eeg_rst <= 1'b0 ;
|
||||
bram_eeg_we <= 0 ;
|
||||
|
||||
trigger_tdata <= 0 ;
|
||||
trigger_tvalid <= 1'b0 ;
|
||||
|
||||
axis_record_tready <= 1'b1;
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
task read_bram_eeg;
|
||||
input [12:0] addr;
|
||||
output [31:0] data;
|
||||
begin
|
||||
@ ( posedge clk );
|
||||
bram_eeg_addr <= addr;
|
||||
bram_eeg_en <= 1;
|
||||
bram_eeg_we <= 4'h0;
|
||||
@ ( posedge clk );
|
||||
bram_eeg_en <= 0;
|
||||
@ ( posedge clk );
|
||||
data <= bram_eeg_dout;
|
||||
end
|
||||
endtask
|
||||
|
||||
task write_bram_eeg;
|
||||
input [12:0] addr;
|
||||
input [31:0] data;
|
||||
begin
|
||||
@ ( posedge clk );
|
||||
bram_eeg_addr <= addr;
|
||||
bram_eeg_din <= data;
|
||||
bram_eeg_en <= 1;
|
||||
bram_eeg_we <= 4'hF;
|
||||
@ ( posedge clk );
|
||||
bram_eeg_en <= 0;
|
||||
bram_eeg_we <= 4'h0;
|
||||
end
|
||||
endtask
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
|
||||
generate
|
||||
for(i=0;i<CHIPSET_QTY;i=i+1) begin : mapping_spi
|
||||
assign cs[i] = cs_w[i];
|
||||
assign sclk[i] = sclk_w[i/2];
|
||||
assign mosi[i] = mosi_w[i/2];
|
||||
assign start[i] = start_w;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i=0;i<SPIS_QTY;i=i+1) begin : mapping_reg
|
||||
assign drdy_w[i] = drdy[2*i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign miso_w[0] = (~cs_w[0])? miso[0]:((~cs_w[1])? miso[1]:1'bZ);
|
||||
assign miso_w[1] = (~cs_w[2])? miso[2]:((~cs_w[3])? miso[3]:1'bZ);
|
||||
assign miso_w[2] = (~cs_w[4])? miso[4]:((~cs_w[5])? miso[5]:1'bZ);
|
||||
assign miso_w[3] = (~cs_w[6])? miso[6]:((~cs_w[7])? miso[7]:1'bZ);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,171 @@
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module eeg_upload#
|
||||
(
|
||||
parameter CLK_PERIOD = 10 ,
|
||||
parameter CHIPSET_QTY = 4 ,
|
||||
parameter CH_OF_CHIPSET = 16 ,
|
||||
parameter TIME_OUT_MS = 5
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst_n ,
|
||||
|
||||
input trans_round ,
|
||||
|
||||
input [32*CHIPSET_QTY-1:0] cnv_res_tdata_array ,
|
||||
input [ CHIPSET_QTY-1:0] cnv_res_tlast_array ,
|
||||
output [ CHIPSET_QTY-1:0] cnv_res_tready_array ,
|
||||
input [ CHIPSET_QTY-1:0] cnv_res_tvalid_array ,
|
||||
|
||||
output reg [31:0] axi_str_rxd_tdata ,
|
||||
output reg axi_str_rxd_tlast ,
|
||||
input axi_str_rxd_tready ,
|
||||
output reg axi_str_rxd_tvalid
|
||||
);
|
||||
|
||||
//*****************************************************************************
|
||||
// localparam definition
|
||||
//*****************************************************************************
|
||||
localparam IDLE = 4'd0 ;
|
||||
localparam READY_ST = 4'd1 ;
|
||||
localparam SCAN_ST = 4'd2 ;
|
||||
|
||||
localparam CLKS = 20 ;
|
||||
localparam TIME_OUT_CLKS = (TIME_OUT_MS*1000000)/CLK_PERIOD;
|
||||
|
||||
//*****************************************************************************
|
||||
// Internal register and wire declarations
|
||||
//*****************************************************************************
|
||||
reg [ 4-1:0] cstate ;
|
||||
reg [ 4-1:0] nstate ;
|
||||
|
||||
wire [32-1:0] cnv_res_tdata[0:CHIPSET_QTY-1] ;
|
||||
wire cnv_res_tlast[0:CHIPSET_QTY-1] ;
|
||||
reg cnv_res_tready[0:CHIPSET_QTY-1] ;
|
||||
wire cnv_res_tvalid[0:CHIPSET_QTY-1] ;
|
||||
|
||||
reg [32-1:0] cnv_res_tdata_r[0:CHIPSET_QTY-1] ;
|
||||
reg cnv_res_tvalid_r[0:CHIPSET_QTY-1] ;
|
||||
|
||||
reg [ 8-1:0] scan_cnt ;
|
||||
|
||||
reg round_end ;
|
||||
|
||||
genvar i;
|
||||
|
||||
//*****************************************************************************
|
||||
generate
|
||||
for(i=0;i<CHIPSET_QTY;i=i+1) begin : rx_data
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
cnv_res_tdata_r[i] <= 0;
|
||||
cnv_res_tvalid_r[i] <= 1'b0;
|
||||
end else if ( cnv_res_tready[i] && cnv_res_tvalid[i] ) begin
|
||||
cnv_res_tdata_r[i] <= cnv_res_tdata[i];
|
||||
cnv_res_tvalid_r[i] <= cnv_res_tvalid[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
round_end <= 1'b0;
|
||||
else if ( cnv_res_tready[0] && cnv_res_tvalid[0] && cnv_res_tlast[0] )
|
||||
round_end <= 1'b1;
|
||||
else if ( cstate == IDLE )
|
||||
round_end <= 1'b0;
|
||||
end
|
||||
|
||||
always@( posedge clk or negedge rst_n ) begin
|
||||
if( !rst_n ) cstate <= IDLE;
|
||||
else cstate <= nstate;
|
||||
end
|
||||
|
||||
always@( * ) begin
|
||||
case ( cstate )
|
||||
IDLE:
|
||||
if ( trans_round )
|
||||
nstate <= READY_ST;
|
||||
else
|
||||
nstate <= IDLE;
|
||||
READY_ST:
|
||||
if ( cnv_res_tvalid_array )
|
||||
nstate <= SCAN_ST;
|
||||
else
|
||||
nstate <= READY_ST;
|
||||
SCAN_ST:
|
||||
if ( scan_cnt == CHIPSET_QTY-1 )
|
||||
nstate <= round_end? IDLE:READY_ST;
|
||||
else
|
||||
nstate <= SCAN_ST;
|
||||
default:
|
||||
nstate <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
generate
|
||||
for(i=0;i<CHIPSET_QTY;i=i+1) begin : tready
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
cnv_res_tready[i] <= 1'b0;
|
||||
else if ( cstate == IDLE || (cstate == READY_ST && nstate == READY_ST) )
|
||||
cnv_res_tready[i] <= 1'b1;
|
||||
else
|
||||
cnv_res_tready[i] <= 1'b0;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
scan_cnt <= 0;
|
||||
else if ( cstate == READY_ST )
|
||||
scan_cnt <= 0;
|
||||
else if ( cstate == SCAN_ST )
|
||||
scan_cnt <= scan_cnt + 1'b1;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n ) begin
|
||||
axi_str_rxd_tvalid <= 1'b0;
|
||||
axi_str_rxd_tdata <= 0;
|
||||
end else if ( cstate == SCAN_ST ) begin
|
||||
axi_str_rxd_tvalid <= cnv_res_tvalid_r[scan_cnt];
|
||||
axi_str_rxd_tdata <= cnv_res_tdata_r[scan_cnt];
|
||||
end else begin
|
||||
axi_str_rxd_tvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ ( posedge clk or negedge rst_n ) begin
|
||||
if ( !rst_n )
|
||||
axi_str_rxd_tlast <= 1'b0;
|
||||
else if ( cstate == SCAN_ST && (scan_cnt == CHIPSET_QTY-1) && round_end )
|
||||
axi_str_rxd_tlast <= 1'b1;
|
||||
else
|
||||
axi_str_rxd_tlast <= 1'b0;
|
||||
end
|
||||
|
||||
//*****************************************************************************
|
||||
// Wire assignment
|
||||
//*****************************************************************************
|
||||
|
||||
generate
|
||||
for(i=0;i<CHIPSET_QTY;i=i+1) begin : unpack_res
|
||||
|
||||
assign cnv_res_tdata[i][31:24] = cnv_res_tdata_array[32*i+31 : 32*i+24] + CH_OF_CHIPSET*i;
|
||||
assign cnv_res_tdata[i][23: 0] = cnv_res_tdata_array[32*i+23 : 32*i+ 0];
|
||||
assign cnv_res_tlast[i] = cnv_res_tlast_array[i];
|
||||
assign cnv_res_tvalid[i] = cnv_res_tvalid_array[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i=0;i<CHIPSET_QTY;i=i+1) begin : pack_res
|
||||
assign cnv_res_tready_array[i] = cnv_res_tready[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user