1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-13 23:26:27 +00:00
2015-11-26 13:52:16 +01:00

67 lines
1.4 KiB
Verilog

// A simple system-on-a-chip (SoC) for the MiST
// (c) 2015 Till Harbaum
module spi (
input reset,
input clk,
// CPU interface
input sel,
input wr,
input addr, // only 1 address bit required
input [7:0] din,
output [7:0] dout,
// SPI/SD card interface
output reg spi_ss,
output reg spi_sck,
output spi_sdo,
input spi_sdi
);
// SPI SS bit is just a cpu controlled output port
always @(negedge clk) begin
if(reset)
spi_ss <= 1'b1;
else begin
// ss is written on io addr 1
if(sel && wr && addr)
spi_ss <= din[0];
end
end
// data is being sent with msb first
assign spi_sdo = spi_tx_byte[7];
reg [3:0] spi_state_cnt;
reg [7:0] spi_tx_byte;
reg [7:0] spi_rx_byte;
always @(negedge clk) begin
if(reset) begin
spi_state_cnt <= 4'd0;
spi_sck <= 1'b0;
end else begin
if(sel && wr && !addr) begin
spi_state_cnt <= 4'd15;
spi_tx_byte <= din;
end else begin
// rising spi clock on odd states
spi_sck <= spi_state_cnt[0];
// read input bit on rising clock edge, shift output bit on falling edge
if(spi_state_cnt[0])
spi_rx_byte <= { spi_rx_byte[6:0], spi_sdi };
else
spi_tx_byte <= { spi_tx_byte[6:0], 1'b0 };
// decrease state counter
if(spi_state_cnt != 0)
spi_state_cnt <= spi_state_cnt - 4'd1;
end
end
end
assign dout = spi_rx_byte;
endmodule