242 lines
6.1 KiB
Verilog
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
|