blob: ede9996d4f2aec8f0d83c16628245770e5140b07 [file] [log] [blame]
module spi_master_tx (
clk,
rstn,
en,
tx_edge,
tx_done,
sdo0,
sdo1,
sdo2,
sdo3,
en_quad_in,
counter_in,
counter_in_upd,
data,
data_valid,
data_ready,
clk_en_o
);
input wire clk;
input wire rstn;
input wire en;
input wire tx_edge;
output wire tx_done;
output wire sdo0;
output wire sdo1;
output wire sdo2;
output wire sdo3;
input wire en_quad_in;
input wire [15:0] counter_in;
input wire counter_in_upd;
input wire [31:0] data;
input wire data_valid;
output reg data_ready;
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 [0:0] tx_CS;
reg [0:0] tx_NS;
assign sdo0 = (en_quad_in ? data_int[28] : data_int[31]);
assign sdo1 = data_int[29];
assign sdo2 = data_int[30];
assign sdo3 = data_int[31];
assign tx_done = done;
assign reg_done = (!en_quad_in && (counter[4:0] == 5'b11111)) || (en_quad_in && (counter[2:0] == 3'b111));
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)) && tx_edge;
always @(*) begin
tx_NS = tx_CS;
clk_en_o = 1'b0;
data_int_next = data_int;
data_ready = 1'b0;
counter_next = counter;
case (tx_CS)
1'd0: begin
clk_en_o = 1'b0;
if (en && data_valid) begin
data_int_next = data;
data_ready = 1'b1;
tx_NS = 1'd1;
end
end
1'd1: begin
clk_en_o = 1'b1;
if (tx_edge) begin
counter_next = counter + 1;
data_int_next = (en_quad_in ? {data_int[27:0], 4'b0000} : {data_int[30:0], 1'b0});
if (tx_done) begin
counter_next = 0;
if (en && data_valid) begin
data_int_next = data;
data_ready = 1'b1;
tx_NS = 1'd1;
end
else begin
clk_en_o = 1'b0;
tx_NS = 1'd0;
end
end
else if (reg_done)
if (data_valid) begin
data_int_next = data;
data_ready = 1'b1;
end
else begin
clk_en_o = 1'b0;
tx_NS = 1'd0;
end
end
end
endcase
end
always @(posedge clk or negedge rstn)
if (~rstn) begin
counter <= 0;
counter_trgt <= 'h8;
data_int <= 'h0;
tx_CS <= 1'd0;
end
else begin
counter <= counter_next;
counter_trgt <= counter_trgt_next;
data_int <= data_int_next;
tx_CS <= tx_NS;
end
endmodule