blob: ece9ffd0736bf71effd1c2f339f736257b2bc6d1 [file] [log] [blame]
//////////////////////////////////////////////////////////////////////
//// ////
//// Single SPI Master Interface Module ////
//// ////
//// This file is part of the riscduino cores project ////
//// https://github.com/dineshannayya/riscduino.git ////
//// ////
//// Description ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// Author(s): ////
//// - Dinesh Annayya, dinesha@opencores.org ////
//// ////
//// Revision : ////
//// V.0 - 06 Oct 2021 ////
//// Initial SpI Module picked from ////
//// http://www.opencores.org/cores/turbo8051/ ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
module sspim_if
(
input logic clk,
input logic reset_n,
input logic sck_int,
input logic cs_int_n,
input logic cfg_bit_order, // 1 -> LSBFIRST or 0 -> MSBFIRST
input logic load_byte,
input logic [1:0] cfg_tgt_sel,
input logic [7:0] byte_out,
input logic sck_active,
input logic shift,
input logic sample,
output logic [7:0]byte_in,
output logic sck,
output logic so,
output logic [3:0]cs_n,
input logic si
);
logic [7:0] so_reg;
logic [7:0] si_reg;
wire shift_out = shift & sck_active;
wire sample_in = sample & sck_active;
//Output Shift Register
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
so_reg <= 8'h00;
so <= 1'b0;
end
else begin
if(load_byte) begin
so_reg <= byte_out;
if(shift_out) begin
// Handling backto back case :
// Last Transfer bit + New Trasfer Load
if(cfg_bit_order) so <= so_reg[0]; // LSB FIRST
else so <= so_reg[7]; // MSB FIRST
end
end // if (load_byte)
else begin
if(shift_out) begin
if(cfg_bit_order) begin // LSB FIRST
so <= so_reg[0];
so_reg <= {1'b0,so_reg[7:1]};
end else begin
so <= so_reg[7];
so_reg <= {so_reg[6:0],1'b0};
end
end // if (shift_out)
end // else: !if(load_byte)
end // else: !if(!reset_n)
end // always @ (posedge clk or negedge reset_n)
// Input shift register
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
si_reg <= 8'h0;
end else begin
if(sample_in) begin
if(cfg_bit_order) begin // LSB FIRST
si_reg[7:0] <= {si,si_reg[7:1]};
end else begin // MSB FIRST
si_reg[7:0] <= {si_reg[6:0],si};
end
end // if (sample_in)
end // else: !if(!reset_n)
end // always @ (posedge clk or negedge reset_n)
assign byte_in[7:0] = si_reg[7:0];
assign cs_n[0] = (cfg_tgt_sel[1:0] == 2'b00) ? cs_int_n : 1'b1;
assign cs_n[1] = (cfg_tgt_sel[1:0] == 2'b01) ? cs_int_n : 1'b1;
assign cs_n[2] = (cfg_tgt_sel[1:0] == 2'b10) ? cs_int_n : 1'b1;
assign cs_n[3] = (cfg_tgt_sel[1:0] == 2'b11) ? cs_int_n : 1'b1;
assign sck = sck_int;
endmodule