Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: azonenberg/openfpga
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 546ceb64a3f2
Choose a base ref
...
head repository: azonenberg/openfpga
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b3f3b557f6ac
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jun 25, 2017

  1. Copy the full SHA
    bae7c52 View commit details

Commits on Jun 26, 2017

  1. Added configurable-edge flipflop for use in the macrocell. Supports a…

    …sync set/reset and rising/falling/DDR edges. No latch support yet.
    azonenberg committed Jun 26, 2017
    Copy the full SHA
    b3f3b55 View commit details
Showing with 292 additions and 0 deletions.
  1. +68 −0 hdl/xc2c-model/ConfigurableEdgeFlipflop.v
  2. +156 −0 hdl/xc2c-model/HandshakeSynchronizer.v
  3. +68 −0 hdl/xc2c-model/ThreeStageSynchronizer.v
68 changes: 68 additions & 0 deletions hdl/xc2c-model/ConfigurableEdgeFlipflop.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
`default_nettype none
/***********************************************************************************************************************
* Copyright (C) 2016-2017 Andrew Zonenberg and contributors *
* *
* This program 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 program 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 program; if not, you may *
* find one here: *
* https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt *
* or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
**********************************************************************************************************************/
module ConfigurableEdgeFlipflop(
d, clk, ce, sr, srval, q, rising_en, falling_en
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// I/O declarations

input wire d;
input wire clk;
input wire ce;
output wire q;
input wire sr;
input wire srval;

input wire rising_en;
input wire falling_en;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The actual FFs

//Rising edge
wire rising_ff;
FDCPE #(
.INIT(1'b0)
) rising (
.Q(rising_ff),
.C(clk),
.CE(ce & rising_en),
.CLR(sr && srval==0),
.D(d ^ falling_ff),
.PRE(sr && srval==1)
);

//Falling edge
wire falling_ff;
FDCPE #(
.INIT(1'b0)
) falling (
.Q(falling_ff),
.C(!clk),
.CE(ce & falling_en),
.CLR(sr), //always clear this FF to zero
.D(d ^ rising_ff),
.PRE(1'b0)
);

//XOR the outputs together
assign q = rising_ff ^ falling_ff;

endmodule
156 changes: 156 additions & 0 deletions hdl/xc2c-model/HandshakeSynchronizer.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
`timescale 1ns / 1ps
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2017 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Handshake synchronizer for sharing a data buffer across two clock domains
This module arbitrates a unidirectional transfer of data from port A to port B through an external buffer.
To send data (port A)
Load data into the buffer
Assert en_a for one cycle
busy_a goes high
Wait for ack_a to go high
The buffer can now be written to again
To receive data (port B)
Wait for en_b to go high
Read data
Assert ack_b for one cycle
Data buffer is now considered invalid, do not touch
*/
module HandshakeSynchronizer(
input wire clk_a,
input wire en_a,
output reg ack_a = 0,
output wire busy_a,

input wire clk_b,
output reg en_b = 0,
input wire ack_b
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Flag synchronizers

reg tx_en_in = 0;
wire tx_en_out;

reg tx_ack_in = 0;
wire tx_ack_out;

ThreeStageSynchronizer sync_tx_en
(.clk_in(clk_a), .din(tx_en_in), .clk_out(clk_b), .dout(tx_en_out));
ThreeStageSynchronizer sync_tx_ack
(.clk_in(clk_b), .din(tx_ack_in), .clk_out(clk_a), .dout(tx_ack_out));

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Control logic, transmit side

reg[1:0] state_a = 0;

assign busy_a = state_a[1] || en_a;

always @(posedge clk_a) begin

ack_a <= 0;

case(state_a)

//Idle - sit around and wait for input to arrive
0: begin
if(en_a) begin
tx_en_in <= 1;
state_a <= 1;
end
end

//Data sent, wait for it to be acknowledged
1: begin
if(tx_ack_out) begin
tx_en_in <= 0;
state_a <= 2;
end
end

//When acknowledge flag goes low the receiver is done with the data.
//Tell the sender and we're done.
2: begin
if(!tx_ack_out) begin
ack_a <= 1;
state_a <= 0;
end
end

endcase

end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Control logic, receive side

reg[1:0] state_b = 0;
always @(posedge clk_b) begin

en_b <= 0;

case(state_b)

//Idle - sit around and wait for input to arrive
0: begin
if(tx_en_out) begin
en_b <= 1;
state_b <= 1;
end
end

//Data received, wait for caller to process it
1: begin
if(ack_b) begin
tx_ack_in <= 1;
state_b <= 2;
end
end

//When transmit flag goes low the sender knows we're done
2: begin
if(!tx_en_out) begin
state_b <= 0;
tx_ack_in <= 0;
end
end

endcase

end

endmodule
68 changes: 68 additions & 0 deletions hdl/xc2c-model/ThreeStageSynchronizer.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
`timescale 1ns / 1ps
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2017 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Three-stage flipflop-based synchronizer
*/
module ThreeStageSynchronizer(
input wire clk_in,
input wire din,
input wire clk_out,
output wire dout
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The flipflops

//Set false to skip the first FF stage (if input is already registered, or totally async)
parameter IN_REG = 1;

wire dout0; //The cross-clock path
wire dout1;
wire dout2;

//First stage: either a FF in the transmitting clock domain, or nothing
generate

if(!IN_REG)
assign dout0 = din;
else
FDCE stage0 (.Q(dout0), .C(clk_in), .CE(1'b1), .CLR(1'b0), .D(din));

endgenerate

//Three stages in the receiving clock domain
(* RLOC="X0Y0" *) FDCE stage1 (.Q(dout1), .C(clk_out), .CE(1'b1), .CLR(1'b0), .D(dout0));
(* RLOC="X0Y0" *) FDCE stage2 (.Q(dout2), .C(clk_out), .CE(1'b1), .CLR(1'b0), .D(dout1));
(* RLOC="X0Y0" *) FDCE stage3 (.Q(dout ), .C(clk_out), .CE(1'b1), .CLR(1'b0), .D(dout2));

endmodule