SPI Code
SPI Code
0) - 8-bit Clock divider to obtain slower speeds - Synthesizable and tested on Xport 2.0 Limitations: - Only supports master mode - Only supports MSB first data read/write - Only supports sampling on rising edge and setup on falling edge - Only 8-bit data transfers - no IRQ support but has a busy bit that can be polled to assure module is not busy - !SS pin has to be controlled by GPIO Copyright (C) 2007 Steven Yu
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */
module spi_master(addr, in_data, out_data, rd, wr, cs, clk, miso, mosi, sclk); input wire [1:0] addr; input wire [7:0] in_data; output reg [7:0] out_data; input wire rd; input wire wr; input wire cs; input wire clk; inout miso; inout mosi; inout sclk; reg sclk_buffer = 0; reg mosi_buffer = 0; reg busy = 0; reg reg reg reg reg [7:0] [7:0] [7:0] [7:0] [4:0] in_buffer = 0; out_buffer = 0; clkcount = 0; clkdiv = 0; count = 0;
begin out_data = 8'bx; if(cs && rd) begin case(addr) 2'b00: begin out_data = out_buffer; end 2'b01: begin out_data = {7'b0, busy}; end 2'b10: begin out_data = clkdiv; end endcase end end always@(posedge clk) begin if(!busy) begin if(cs && wr) begin case(addr) 2'b00: begin in_buffer = in_data; busy = 1'b1; end 2'b10: begin clkdiv = in_data; end endcase end end else begin clkcount = clkcount + 1; if(clkcount >= clkdiv) begin clkcount = 0; if((count % 2) == 0) begin mosi_buffer = in_buffer[7]; in_buffer = in_buffer << 1; end if(count > 0 && count < 17) begin sclk_buffer = ~sclk_buffer; end count = count + 1; if(count > 17) begin count = 0; busy = 1'b0; end end end end always@(posedge sclk_buffer) begin out_buffer = out_buffer << 1; out_buffer[0] = miso;