blob: 8885afc5897eda9df8c81842aa8af938a560d6ac [file] [log] [blame]
module spi_master_rx (
clk,
rstn,
en,
rx_edge,
rx_done,
sdi0,
sdi1,
sdi2,
sdi3,
en_quad_in,
counter_in,
counter_in_upd,
data,
data_ready,
data_valid,
clk_en_o
);
input wire clk;
input wire rstn;
input wire en;
input wire rx_edge;
output wire rx_done;
input wire sdi0;
input wire sdi1;
input wire sdi2;
input wire sdi3;
input wire en_quad_in;
input wire [15:0] counter_in;
input wire counter_in_upd;
output wire [31:0] data;
input wire data_ready;
output reg data_valid;
output reg clk_en_o;
reg [31:0] data_int;
reg [31:0] data_int_next;
reg [15:0] counter;
reg [15:0] counter_trgt;
reg [15:0] counter_next;
reg [15:0] counter_trgt_next;
wire done;
wire reg_done;
reg [1:0] rx_CS;
reg [1:0] rx_NS;
assign reg_done = (!en_quad_in && (counter[4:0] == 5'b11111)) || (en_quad_in && (counter[2:0] == 3'b111));
assign data = data_int_next;
assign rx_done = done;
always @(*)
if (counter_in_upd)
counter_trgt_next = (en_quad_in ? {2'b00, counter_in[15:2]} : counter_in);
else
counter_trgt_next = counter_trgt;
assign done = (counter == (counter_trgt - 1)) && rx_edge;
always @(*) begin
rx_NS = rx_CS;
clk_en_o = 1'b0;
data_int_next = data_int;
data_valid = 1'b0;
counter_next = counter;
case (rx_CS)
2'd0: begin
clk_en_o = 1'b0;
if (en)
rx_NS = 2'd1;
end
2'd1: begin
clk_en_o = 1'b1;
if (rx_edge) begin
counter_next = counter + 1;
if (en_quad_in)
data_int_next = {data_int[27:0], sdi3, sdi2, sdi1, sdi0};
else
data_int_next = {data_int[30:0], sdi0};
if (rx_done) begin
counter_next = 0;
data_valid = 1'b1;
if (data_ready)
rx_NS = 2'd0;
else
rx_NS = 2'd3;
end
else if (reg_done) begin
data_valid = 1'b1;
if (~data_ready) begin
clk_en_o = 1'b0;
rx_NS = 2'd2;
end
end
end
end
2'd3: begin
data_valid = 1'b1;
if (data_ready)
rx_NS = 2'd0;
end
2'd2: begin
data_valid = 1'b1;
if (data_ready)
rx_NS = 2'd1;
end
endcase
end
always @(posedge clk or negedge rstn)
if (rstn == 0) begin
counter <= 0;
counter_trgt <= 'h8;
data_int <= 1'sb0;
rx_CS <= 2'd0;
end
else begin
counter <= counter_next;
counter_trgt <= counter_trgt_next;
data_int <= data_int_next;
rx_CS <= rx_NS;
end
endmodule