Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module spi (
- input clk,
- input clk_en, // assumed to get the correct enables for the freq we need 100Khz etc.
- input reset,
- input enable,
- input [39:0] cmd_data, // command data.
- output reg rsp_rdy, // read pulse
- output [15:0] rsp_count, // bytes read this respose cycle.
- output reg [7:0] rsp_data, // response data.
- // raw spi bus.
- output spi_clk,
- input spi_miso,
- output spi_mosi,
- output spi_cs_n);
- // states
- localparam idle=0, warmup=1, cmd=2, rsp=3;
- // warmup counter
- wire warmup_complete;
- reg [15:0] warmup_count = 16'd0;
- // spi clock register
- reg clk_r = 1'b0;
- reg [18:0] shift_count = 19'd0;
- reg [47:0] shift_reg = {48{1'b1}};
- reg [1:0] mode = idle;
- reg [1:0] mode_r = idle;
- always @(posedge clk)
- begin
- if (reset) begin
- clk_r <= 1'b0;
- mode <= warmup;
- shift_reg = {48{1'b1}};
- shift_count = 19'd0;
- warmup_count <= 16'd0;
- end else if (clk_en) begin
- case (mode)
- idle: begin // idle logic
- byte_count <= 3'd0;
- if (enable) begin
- mode <= cmd; // now we start clocking out the command
- shift_reg <= cmd_data;
- end
- end
- warmup: begin // warmup logic
- if (warmup_complete & !clk_r) begin
- mode <= idle;
- end else begin
- warmup_count <= warmup_count + 16'd1;
- end
- end
- cmd: begin // send a command. 6 bytes
- if (!clk_r) begin
- shift_reg <= {shift_reg[46:0], 1'b1};
- end
- // if we've shifted out 6 bytes then we're done.
- if (shift_counter == {16'd5,3'b111}) begin
- mode <= read;
- end
- end
- read: begin
- if (!clk_r) begin
- shift_reg[7:0] <= {shift_reg[6:0], spi_miso};
- if (shift_count[2:0] == 3'b111) begin
- rsp_data <= {shift_reg[6:0], spi_miso};
- rsp_rdy <= 1'b1;
- end
- end else begin
- rsp_rdy <= 1'b0;
- end
- if (!enable) begin
- mode <= idle;
- end
- end
- endcase
- // clock output
- if ((mode != idle) | (shift_count[2:0] != 3'd0)) begin
- clk_r <= !clk_r;
- if (clk_r) begin
- // if the state mode changes reset the count.
- if (mode_r != mode) begin
- shift_count <= 19'd0;
- end else begin
- shift_count <= shift_count + 19'd1;
- end
- mode_r <= mode;
- end
- end else begin
- clk_r <= 1'b0;
- end
- end
- end
- assign warmup_complete = warmup_count >= 80 * 8;
- assign spi_mosi = shift_reg[47];
- assign spi_cs_n = !warmup_complete;
- assign rsp_count = shift_count[18:3] & {16{(mode == read)}};
- endmodule
Add Comment
Please, Sign In to add comment