blob: 9b970affb02cb26fa1a19bfe22af5822fa86c63e [file] [log] [blame]
`default_nettype none
// Simple I/O expander
//
// Input pinout:
// 0 clk logic clock
// 1 reset logic reset (positive)
// 2 sclk spi clock
// 3 CE spi chip enable (negative)
// 4 sin spi in (into this device)
// 5 IN0 input 0
// 6 IN1 input 1
// 7 IN2 input 2
//
// Output pinout:
// 0 OUT0
// 1 OUT1
// 2 OUT2
// 3 OUT3
// 4 OUT4
// 5 OUT5
// 6 OUT6
// 7 sout spi out (out of this device)
// Top level io for this module should stay the same to fit into the scan_wrapper.
// The pin connections within the user_module are up to you,
// although (if one is present) it is recommended to place a clock on io_in[0].
// This allows use of the internal clock divider if you wish.
module user_module_341432284947153491(
input [7:0] io_in,
output [7:0] io_out
);
wire clk, reset, sclk, ce, sin, in0, in1, in2;
assign clk = io_in[0];
assign reset = io_in[1];
assign sclk = io_in[2];
assign ce = io_in[3];
assign sin = io_in[4];
assign in0 = io_in[5];
assign in1 = io_in[6];
assign in2 = io_in[7];
wire [6:0] out;
wire sout;
assign io_out = { sout, out };
wire [2:0] ioexp_in;
assign ioexp_in = { io_in[7], io_in[6], io_in[5] };
spi_341432284947153491 #(.INBITS(3), .OUTBITS(7)) spi_core (
.reset(reset),
.clk(clk),
.sclk(sclk),
.ce(ce),
.sin(sin),
.sout(sout),
.inputs(ioexp_in),
.outputs(out)
);
// The SPI module latches in the inputs on neg CE and latches out the
// outputs on pos CE
endmodule
// SPI in, shift in new output while shifting out old outputs
module spi_341432284947153491 #(
parameter INBITS = 4,
parameter OUTBITS = 4
) (
input reset, // synchronous internal reset
input clk, // system clock
input sclk, // negative polarity
input ce, // active low
input sin,
output sout,
input [INBITS-1:0] inputs,
output [OUTBITS-1:0] outputs
);
// Note: We shift IN the IO OUTPUTS. We shift OUT the IO INPUTS.
reg [OUTBITS-1:0] inlatch; // serial input latch (latch on CE rising edge)
reg [OUTBITS-1:0] inbuf; // serial input buffer (latch on CE rising edge)
reg [INBITS-1:0] outlatch; // serial output latch (latch on CE falling edge)
assign sout = outlatch[0];
assign outputs = inlatch;
wire ce_posedge, ce_negedge;
posedge_341432284947153491 pe_ce(.clk(clk), .in(ce), .pedge(ce_posedge));
negedge_341432284947153491 ne_ce(.clk(clk), .in(ce), .nedge(ce_negedge));
wire sclk_posedge, sclk_negedge;
posedge_341432284947153491 pe_sclk(.clk(clk), .in(sclk), .pedge(sclk_posedge));
negedge_341432284947153491 ne_sclk(.clk(clk), .in(sclk), .nedge(sclk_negedge));
always @(posedge clk) begin
if (reset) begin
inbuf <= 0;
inlatch <= 0;
outlatch <= 0;
end else if (ce_posedge) begin
inlatch <= inbuf;
end else if (ce_negedge) begin
outlatch <= inputs;
//end else if (ce) begin
//inbuf <= 0;
//outlatch <= 0;
end else begin
if (sclk_posedge) begin
outlatch <= { 1'b0, outlatch[INBITS-1:1] };
end else if (sclk_negedge) begin
inbuf <= { inbuf[OUTBITS-2:0], sin };
end
end
end
endmodule
module posedge_341432284947153491(input clk, input in, output pedge);
reg last, now;
assign pedge = !last && now;
always @(posedge clk) begin
{last, now} = {now, in};
end
endmodule
module negedge_341432284947153491(input clk, input in, output nedge);
reg last, now;
assign nedge = last && !now;
always @(posedge clk) begin
{last, now} = {now, in};
end
endmodule