Files
2024-10-28 13:14:49 +08:00

242 lines
6.1 KiB
Verilog

`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