Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module SPI_Master(
- (* keep = "true", mark_debug = "true" *) input logic [47:0] cmd_from_accel, //Master **IN**: Data to send on MOSI
- input logic fpga_reset, // Reset Pin from FPGA Board
- input logic fpga_clk, // FPGA Clock
- input logic [5:0] init_bit_count,
- input logic [5:0] data_bit_count,
- (* keep = "true", mark_debug = "true" *) input logic miso, // Transfer TX data one bit at a time
- (* keep = "true", mark_debug = "true" *) input logic start_transaction, // Comes from accelerometer
- input logic fifo_full,
- (* keep = "true", mark_debug = "true" *) input logic data_read,
- (* keep = "true", mark_debug = "true" *) input logic init_instruct,
- (* keep = "true", mark_debug = "true" *) output logic [47:0] data_to_fifo, //Master **OUT**: Data received from MISO
- (* keep = "true", mark_debug = "true" *) output logic mosi, // Transfer RX data one bit at a time to mosi
- (* keep = "true", mark_debug = "true" *) output logic cs, // Chip Select Pin
- (* keep = "true", mark_debug = "true" *) output logic spi_clk, // SPI Clock
- (* keep = "true", mark_debug = "true" *) output logic end_transaction
- );
- typedef enum logic [3:0] {
- IDLE,
- LOAD,
- CS_SETUP,
- CS_HOLD,
- INIT_TRANSFER,
- DATA_TRANSFER,
- CS_FINISH,
- FINISH
- } e_state;
- (* keep = "true", mark_debug = "true" *) logic [5:0] init_spi_clk_counter;
- (* keep = "true", mark_debug = "true" *) logic [5:0] data_spi_clk_counter;
- logic [5:0] div_counter;
- logic [7:0] cs_setup_counter;
- (* keep = "true", mark_debug = "true" *) e_state state;
- logic sclk_q;
- (* keep = "true", mark_debug = "true" *) wire lead = (spi_clk & ~sclk_q); // rising edge
- (* keep = "true", mark_debug = "true" *) wire trail = (~spi_clk & sclk_q); // falling edge
- always_ff @(posedge fpga_clk) begin
- if (fpga_reset)
- sclk_q <= 0;
- else
- sclk_q <= spi_clk;
- end
- // CLOCK DIVIDER from 100MHz to 2.5MHz
- always_ff @(posedge fpga_clk) begin
- if (fpga_reset) begin
- div_counter <= 0;
- spi_clk <= 0;
- end else if (state == IDLE || state == FINISH || state == CS_SETUP || state == CS_HOLD || state == CS_FINISH) begin
- spi_clk <= 0;
- div_counter <= 0;
- end else begin
- div_counter <= div_counter + 1;
- if (div_counter == 19) begin
- div_counter <= 0;
- spi_clk <= ~spi_clk;
- end else begin
- end
- end
- end
- always_ff @(posedge fpga_clk) begin
- if (fpga_reset) begin
- init_spi_clk_counter <= 0;
- data_spi_clk_counter <= 0;
- end else begin
- case (state)
- IDLE: begin
- if (fifo_full) begin
- init_spi_clk_counter <= 0;
- data_spi_clk_counter <= 0;
- end else if (start_transaction) begin
- init_spi_clk_counter <= init_bit_count - 1;
- data_spi_clk_counter <= data_bit_count - 1;
- end
- end
- INIT_TRANSFER: if (init_instruct && trail) begin
- if (init_spi_clk_counter != 0)
- init_spi_clk_counter <= init_spi_clk_counter - 1;
- end
- DATA_TRANSFER: if (data_read && trail) begin
- if (data_spi_clk_counter != 0)
- data_spi_clk_counter <= data_spi_clk_counter - 1;
- end
- default: ;
- endcase
- end
- end
- always_ff @(posedge fpga_clk) begin
- if (fpga_reset)
- state <= IDLE;
- else begin
- case (state)
- IDLE: if (start_transaction) state <= LOAD;
- LOAD: begin
- cs_setup_counter <= 0;
- state <= CS_SETUP;
- end
- CS_SETUP: begin
- cs_setup_counter <= cs_setup_counter + 1;
- if (cs_setup_counter == 32) begin
- state <= INIT_TRANSFER;
- end
- end
- INIT_TRANSFER: begin
- if (lead && init_spi_clk_counter == 0)
- state <= (data_read ? DATA_TRANSFER : CS_HOLD);
- end
- DATA_TRANSFER: begin
- if (lead && data_spi_clk_counter == 0)
- state <= CS_HOLD;
- end
- CS_HOLD: begin
- cs_setup_counter <= cs_setup_counter + 1;
- if (cs_setup_counter == 32) begin
- cs_setup_counter <= 0;
- state <= CS_FINISH;
- end
- end
- CS_FINISH: begin
- cs_setup_counter <= cs_setup_counter + 1;
- if (cs_setup_counter == 64) begin
- state <= FINISH;
- end
- end
- FINISH: state <= IDLE;
- default: state <= IDLE;
- endcase
- end
- end
- always_ff @(posedge fpga_clk) begin
- if (fpga_reset) begin
- cs <= 1;
- end_transaction <= 0;
- end else begin
- cs <= (state == IDLE || state == FINISH || state == CS_FINISH) ? 1 : 0;
- end_transaction <= (state == FINISH);
- end
- end
- always_ff @(negedge fpga_clk) begin
- if (fpga_reset) begin
- mosi <= 1'b0;
- end else if (state == INIT_TRANSFER && trail) begin
- if (init_spi_clk_counter > 0)
- mosi <= cmd_from_accel[init_spi_clk_counter];
- end
- end
- always_ff @(posedge fpga_clk) begin
- if (fpga_reset) begin
- data_to_fifo <= 0;
- end else if (state == IDLE) begin
- data_to_fifo <= 0;
- end else if (state == DATA_TRANSFER && lead) begin
- data_to_fifo[data_spi_clk_counter] <= miso;
- end
- end
- endmodule
- //master selects a slave by pulling CS low.
Advertisement
Add Comment
Please, Sign In to add comment