gateware

A collection of little open source FPGA hobby projects
git clone http://frotz.net/git/gateware.git
Log | Files | Refs | README

spi_debug_ifc.v (2892B)


      1 // Copyright 2015, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0.
      3 
      4 `default_nettype none
      5 
      6 `timescale 1ns / 1ps
      7 
      8 module spi_debug_ifc(
      9 	input spi_clk,
     10 	input spi_cs_i,
     11 	input spi_data_i,
     12 	output spi_data_o,
     13 	input sys_clk,
     14 	output sys_wr_o,
     15 	output [15:0]sys_waddr_o,
     16 	output [15:0]sys_wdata_o
     17 	);
     18 
     19 reg [15:0]spi_shift = 16'd0;
     20 reg [16:0]spi_data = 17'd0;
     21 reg [3:0]spi_count = 4'd0;
     22 reg spi_signal = 1'd0;
     23 reg spi_flag = 1'd0;
     24 
     25 assign spi_data_o = 1'b0;
     26 
     27 wire [15:0]spi_next = { spi_data_i, spi_shift[15:1] };
     28 
     29 reg [15:0]spi_shift_next;
     30 reg [16:0]spi_data_next;
     31 reg [3:0]spi_count_next;
     32 reg spi_signal_next;
     33 reg spi_flag_next;
     34 
     35 always @(*) begin
     36 	spi_shift_next = spi_shift;
     37 	spi_data_next = spi_data;
     38 	spi_count_next = spi_count;
     39 	spi_signal_next = spi_signal;
     40 	spi_flag_next = spi_flag;
     41 
     42 	if (spi_cs_i) begin
     43 		spi_count_next = 4'd0;
     44 		spi_flag_next = 1'b1;
     45 	end else begin
     46 		spi_shift_next = spi_next;
     47 		spi_count_next = spi_count + 4'd1;
     48 		if (spi_count == 4'd15) begin
     49 			spi_data_next = { spi_flag, spi_next };
     50 			spi_signal_next = ~spi_signal;
     51 			spi_flag_next = 1'b0;
     52 		end
     53 	end
     54 end
     55 
     56 always @(posedge spi_clk) begin
     57 	spi_shift <= spi_shift_next;
     58 	spi_data <= spi_data_next;
     59 	spi_count <= spi_count_next;
     60 	spi_signal <= spi_signal_next;
     61 	spi_flag <= spi_flag_next;
     62 end
     63 
     64 wire sys_signal;
     65 
     66 sync_oneway sync_spi_sys(
     67 	.txclk(spi_clk),
     68 	.txdat(spi_signal),
     69 	.rxclk(sys_clk),
     70 	.rxdat(sys_signal)
     71 	);
     72 
     73 reg sys_signal_ack = 1'b0;
     74 reg enabled = 1'b0;
     75 reg [15:0]addr;
     76 reg [15:0]data;
     77 reg wr = 1'b0;
     78 
     79 reg [15:0]addr_next;
     80 reg [15:0]data_next;
     81 reg enabled_next;
     82 reg sys_signal_ack_next;
     83 reg wr_next;
     84 
     85 reg [15:0]delay = 16'd0;
     86 reg [15:0]delay_next;
     87 
     88 always @(*) begin
     89 	delay_next = delay;
     90 	addr_next = addr;
     91 	data_next = data;
     92 	sys_signal_ack_next = sys_signal_ack;
     93 	wr_next = wr;
     94 
     95 	// ensure we're up and running before accepting writes
     96 	// there's got to be a nicer way to do this
     97 	if (delay != 16'hFFFF) begin
     98 		delay_next = delay + 1'd1;
     99 		enabled_next = 1'b0;
    100 	end else begin
    101 		enabled_next = 1'b1;
    102 	end
    103 
    104 	if (sys_signal ^ sys_signal_ack) begin
    105 		sys_signal_ack_next = ~sys_signal_ack;
    106 		if (spi_data[16]) begin
    107 			addr_next = spi_data[15:0];
    108 		end else begin
    109 			data_next = spi_data[15:0];
    110 			wr_next = 1'b1;
    111 		end
    112 	end else begin
    113 		if (wr) begin
    114 			wr_next = 1'b0;
    115 			addr_next = addr + 16'd1;
    116 		end
    117 	end
    118 end
    119 
    120 always @(posedge sys_clk) begin
    121 	delay <= delay_next;
    122 	addr <= addr_next;
    123 	data <= data_next;
    124 	enabled <= enabled_next;
    125 	sys_signal_ack <= sys_signal_ack_next;
    126 	wr <= wr_next;
    127 end
    128 
    129 assign sys_wr_o = wr & enabled;
    130 assign sys_waddr_o = addr;
    131 assign sys_wdata_o = data;
    132 
    133 endmodule
    134 
    135 
    136 
    137 module sync_oneway(
    138 	input txclk,
    139 	input txdat,
    140 	input rxclk,
    141 	output rxdat
    142 	);
    143 
    144 reg a = 0;
    145 
    146 // these should be adjacent
    147 reg b = 0, c = 0;
    148 
    149 always @(posedge txclk)
    150 	a <= txdat;
    151 
    152 always @(posedge rxclk) begin
    153 	b <= a;
    154 	c <= b;
    155 end
    156 
    157 assign rxdat = c;
    158 
    159 endmodule