Commit 3be23a0e authored by Mike Lyons's avatar Mike Lyons

Correctly read single-byte incoming transmissions (PC->FPGA).

parent f074d0b9
......@@ -62,6 +62,114 @@ module spiifc(
// Registers
//
reg [ 7: 0] debug_reg;
reg [ 7: 0] rcByteReg;
reg rcStarted;
reg [ 2: 0] rcBitIndexReg;
reg [11: 0] rcMemAddrReg;
reg ssPrev;
reg ssFastToggleReg;
reg ssSlowToggle;
reg ssTurnOnReg;
reg ssTurnOnHandled;
//
// Wires
//
wire rcByteValid;
wire [ 7: 0] rcByte;
wire rcStarting;
wire [ 2: 0] rcBitIndex;
wire ssTurnOn;
wire ssFastToggle;
//
// Output assigns
//
assign debug_out = debug_reg;
assign SPI_MISO = 0;
assign txMemAddr = 0;
assign rcMemAddr = rcMemAddrReg;
assign rcMemData = rcByte;
assign rcMemWE = rcByteValid;
assign ssFastToggle =
(ssPrev == 1 && SPI_SS == 0 ? ~ssFastToggleReg : ssFastToggleReg);
//
// Wire assigns
//
assign rcByteValid = rcStarted && rcBitIndex == 0;
assign rcByte = {rcByteReg[7:1], SPI_MOSI};
assign rcStarting = ssTurnOn;
assign rcBitIndex = (rcStarting ? 3'd7 : rcBitIndexReg);
//assign ssTurnOn = ~ssTurnOnHandled & (ssTurnOnReg | (ssPrev & (~SPI_SS)));
assign ssTurnOn = ssSlowToggle ^ ssFastToggle;
initial begin
ssSlowToggle <= 0;
end
always @(posedge SysClk) begin
ssPrev <= SPI_SS;
if (Reset) begin
ssTurnOnReg <= 0;
ssFastToggleReg <= 0;
end else begin
if (ssPrev & (~SPI_SS)) begin
ssTurnOnReg <= 1;
ssFastToggleReg <= ~ssFastToggleReg;
end else if (ssTurnOnHandled) begin
ssTurnOnReg <= 0;
end
end
end
always @(posedge SPI_CLK) begin
ssSlowToggle <= ssFastToggle;
if (Reset) begin
// Resetting
rcByteReg <= 8'h00;
rcStarted <= 0;
rcBitIndexReg <= 3'd7;
ssTurnOnHandled <= 0;
debug_reg <= 8'hFF;
end else begin
// Not resetting
ssTurnOnHandled <= ssTurnOn;
if (~SPI_SS) begin
rcByteReg[rcBitIndex] <= SPI_MOSI;
rcBitIndexReg <= rcBitIndex - 3'd1;
rcStarted <= 1;
end
// We've just received a byte (well, currently receiving the last bit)
if (rcByteValid) begin
// For now, just display on LEDs
debug_reg <= rcByte;
end
end // Reset/Reset'
end
/*
reg rcByte_valid;
wire rcClockBridgeEmpty;
wire readRcByte;
......@@ -103,10 +211,12 @@ fifo_8bit_to_8bit txCmdClkBridge(
.full(txCmdClkBridgeFull), // output full
.empty(txCmdClkBridgeEmpty) // output empty
);
/*
* TRANSMIT: FPGA TO PC
*/
//
// TRANSMIT: FPGA TO PC
//
assign SPI_MISO = txMemData[bitIndex];
reg [2:0] bitIndex;
......@@ -138,9 +248,9 @@ fifo_8bit_to_8bit txCmdClkBridge(
end
end
/*
* RECEIVE: PC TO FPGA
*/
//
// RECEIVE: PC TO FPGA
//
// Detect start of receive
reg ss_prev;
......@@ -171,22 +281,22 @@ fifo_8bit_to_8bit txCmdClkBridge(
assign rcMemWE = rcMemWE_reg;
always @(posedge SysClk) begin
/*
// About to receive
if (ss_negedge) begin
rcBitIndex <= 3'd7;
rcState <= `RC_STATE_CMD;
debug_reg[0] <= 1;
end
// Receiving
if (receiving) begin
rcByte[rcBitIndex] <= SPI_MOSI;
rcBitIndex <= rcBitIndex - 3'd1;
end
rcByte_valid <= (receiving && rcBitIndex == 3'd0 ? 1'b1 : 1'b0);
*/
// // About to receive
// if (ss_negedge) begin
// rcBitIndex <= 3'd7;
// rcState <= `RC_STATE_CMD;
//
// debug_reg[0] <= 1;
// end
//
// // Receiving
// if (receiving) begin
// rcByte[rcBitIndex] <= SPI_MOSI;
// rcBitIndex <= rcBitIndex - 3'd1;
// end
// rcByte_valid <= (receiving && rcBitIndex == 3'd0 ? 1'b1 : 1'b0);
// Handle the complete incoming byte
if (rcByte_valid) begin
......@@ -270,40 +380,40 @@ fifo_8bit_to_8bit txCmdClkBridge(
//wire [7:0] rcByte;
//assign rcByte = {rcByteReg[7:1], (SPI_SS == 1'b0 && bitIndex ==
/*
//
// Receive (GPU to SPI)
//
reg SPI_SS_prev_cycle;
// This is the register backing rcByteId. It is always one cycle
// behind the true value of rcByteId, which we have to do a little
// work to get instantaneously correct using wire logic.
reg [31:0] rcByteIdPrev;
wire [31:0] rcByteId;
assign rcByteId = (SPI_SS_prev_cycle == 1 && SPI_SS == 0 ? 32'd0 : 32'd1 + rcByteIdPrev);
// 1 if we're receiving from GPC, 0 if not.
wire isRecv;
assign isRecv = ~SPI_SS;
// Bits to Byte aggregator
reg [2:0] rcBitId;
reg [7:0] rcByte;
reg [31:0] rcSizeBytes;
always @(posedge SPI_CLK) begin
if (1 == isRecv) begin
case (rcByteId)
0: rcSizeBytes[ 7: 0] <=
end
// Update registers for next cycle
SPI_SS_prev_cycle <= SPI_SS;
rcByteId <= rcByteIdPrev;
end
*/
// //
// // Receive (GPU to SPI)
// //
// reg SPI_SS_prev_cycle;
//
// // This is the register backing rcByteId. It is always one cycle
// // behind the true value of rcByteId, which we have to do a little
// // work to get instantaneously correct using wire logic.
// reg [31:0] rcByteIdPrev;
// wire [31:0] rcByteId;
// assign rcByteId = (SPI_SS_prev_cycle == 1 && SPI_SS == 0 ? 32'd0 : 32'd1 + rcByteIdPrev);
//
// // 1 if we're receiving from GPC, 0 if not.
// wire isRecv;
// assign isRecv = ~SPI_SS;
//
// // Bits to Byte aggregator
// reg [2:0] rcBitId;
// reg [7:0] rcByte;
//
//
// reg [31:0] rcSizeBytes;
//
// always @(posedge SPI_CLK) begin
// if (1 == isRecv) begin
// case (rcByteId)
// 0: rcSizeBytes[ 7: 0] <=
// end
//
// // Update registers for next cycle
// SPI_SS_prev_cycle <= SPI_SS;
// rcByteId <= rcByteIdPrev;
// end
*/
endmodule
......@@ -39,6 +39,7 @@ module spiifc_tb2;
wire [11:0] rcMemAddr;
wire [7:0] rcMemData;
wire rcMemWE;
wire [7:0] debug_out;
// Instantiate the Unit Under Test (UUT)
spiifc uut (
......@@ -52,7 +53,8 @@ module spiifc_tb2;
.txMemData(txMemData),
.rcMemAddr(rcMemAddr),
.rcMemData(rcMemData),
.rcMemWE(rcMemWE)
.rcMemWE(rcMemWE),
.debug_out(debug_out)
);
task recvByte;
......@@ -71,8 +73,16 @@ module spiifc_tb2;
#20 SysClk = ~SysClk;
end
reg SPI_CLK_en;
initial begin
#310
SPI_CLK_en = 1;
end
always begin
#50 SPI_CLK = ~SPI_CLK;
#10
if (SPI_CLK_en) begin
#40 SPI_CLK = ~SPI_CLK;
end
end
integer fdRcBytes;
......@@ -87,12 +97,19 @@ module spiifc_tb2;
SysClk = 0;
SPI_CLK = 0;
SPI_CLK_en = 0;
SPI_MOSI = 0;
SPI_SS = 1;
txMemData = 0;
// Wait 100 ns for global reset to finish
#100;
Reset = 1;
#100;
Reset = 0;
#100;
// Add stimulus here
SPI_SS = 0;
......
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:49:15 11/02/2011
// Design Name:
// Module Name: spiwrap
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module spiwrap(
input Reset,
input SysClk,
input spi_ss,
input spi_mosi,
input spi_clk,
output spi_miso,
output [7:0] leds
);
wire [31:0] douta_dummy;
wire [11:0] spi_addr;
wire [ 7:0] spi_data;
reg initMem;
reg [ 9:0] initMemAddr;
reg [31:0] initMemData;
always @(posedge SysClk) begin
if (Reset) begin
initMem <= 1'b1;
initMemAddr <= 10'h000;
//initMemData <= 32'hFF00_FF00;
initMemData <= 32'h5A6C_C6A5; /*32'h55CC_55CC*/;
end else begin
if (initMem == 1'b1) begin
// Turn off init mem mode if formatted memory
if (initMemAddr == 10'h3FF) begin
initMem <= 1'b0;
end
// Increment init mem addr/data
initMemAddr <= initMemAddr + 10'h001;
//initMemData <= ~initMemData;
end
end
end
spimem spiMemTx (
.clka(SysClk), // input clka
.ena(1'b1), // input ena
.wea(initMem), // input [0 : 0] wea
.addra(initMemAddr), // input [9 : 0] addra
.dina(initMemData), // input [31 : 0] dina
.douta(douta_dummy), // output [31 : 0] douta
.clkb(spi_clk), // input clkb
.enb(1'b1), // input enb
.web(1'b0), // input [0 : 0] web
.addrb(spi_addr), // input [11 : 0] addrb
.dinb(8'h00), // input [7 : 0] dinb
.doutb(spi_data) // output [7 : 0] doutb
);
wire spi_rcMem_we;
wire [11:0] spi_rcMem_addr;
wire [ 7:0] spi_rcMem_data;
wire [ 7:0] debug_out;
wire [ 7:0] spi_rcMem_doutb_dummy;
spimem spiMemRc (
.clka(SysClk),
.ena(1'b1),
.wea(1'b0),
.addra(10'h000),
.douta(debug_out),
.clkb(spi_clk),
.enb(1'b1),
.web(spi_rcMem_we),
.addrb(spi_rcMem_addr),
.dinb(spi_rcMem_data),
.doutb(spi_rcMem_doutb_dummy)
);
spiifc mySpiIfc (
.Reset(Reset),
.SysClk(SysClk),
.SPI_CLK(spi_clk),
.SPI_MISO(spi_miso),
.SPI_MOSI(spi_mosi),
.SPI_SS(spi_ss),
.txMemAddr(spi_addr),
.txMemData(spi_data),
.rcMemAddr(spi_rcMem_addr),
.rcMemData(spi_rcMem_data),
.rcMemWE(spi_rcMem_we),
.debug_out(leds)
);
//assign leds = debug_out;
endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment