Skip to content

Commit

Permalink
adding the cdc fifo design
Browse files Browse the repository at this point in the history
  • Loading branch information
zerotoasic committed May 29, 2024
1 parent 1d89cae commit 90f8d9d
Show file tree
Hide file tree
Showing 13 changed files with 373 additions and 65 deletions.
41 changes: 24 additions & 17 deletions info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,40 @@ project:

# List your project's source files here. Source files must be in ./src and you must list each source file separately, one per line:
source_files:
- "project.v"
- "tt_um_pa1mantri_cdc_fifo.sv"
- "cdc_fifo.sv"
- "dpram.sv"
- "binary_to_gray.sv"
- "gray_to_binary.sv"
- "synchronizer.sv"
- "cdc_fifo_read_state.sv"
- "cdc_fifo_write_state.sv"

# The pinout of your project. Leave unused pins blank. DO NOT delete or add any pins.
pinout:
# Inputs
ui[0]: ""
ui[1]: ""
ui[2]: ""
ui[3]: ""
ui[4]: ""
ui[5]: ""
ui[6]: ""
ui[7]: ""
ui[0]: "write_clock"
ui[1]: "write_increment"
ui[2]: "read_clock"
ui[3]: "read_increment"
ui[4]: "write_data0"
ui[5]: "write_data1"
ui[6]: "write_data2"
ui[7]: "write_data3"

# Outputs
uo[0]: ""
uo[1]: ""
uo[0]: "empty"
uo[1]: "full"
uo[2]: ""
uo[3]: ""
uo[4]: ""
uo[5]: ""
uo[6]: ""
uo[7]: ""
uo[4]: "read_data0"
uo[5]: "read_data1"
uo[6]: "read_data2"
uo[7]: "read_data3"

# Bidirectional pins
uio[0]: ""
uio[1]: ""
uio[0]: "write_reset"
uio[1]: "read_reset"
uio[2]: ""
uio[3]: ""
uio[4]: ""
Expand Down
10 changes: 10 additions & 0 deletions src/binary_to_gray.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module binary_to_gray #(
parameter WIDTH = 8
) (
input logic [WIDTH-1:0] binary,
output logic [WIDTH-1:0] gray
);

assign gray = (binary >> 1) ^ binary;

endmodule
93 changes: 93 additions & 0 deletions src/cdc_fifo.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// FIFO for passing registers across clock domains

//`include "dpram.sv"
//`include "synchronizer.sv"
//`include "cdc_fifo_read_state.sv"
//`include "cdc_fifo_write_state.sv"
//`include "binary_to_gray.sv"
//`include "gray_to_binary.sv"

module cdc_fifo #(
parameter DATA_WIDTH = 8,
parameter ADDRESS_WIDTH = 4
) (
// Sender side signals/buses
input logic write_clock,
input logic write_reset,
input logic [DATA_WIDTH-1:0] write_data,
input logic write_increment,
output logic full,

// Receiver side signals/buses
input logic read_clock,
input logic read_reset,
input logic read_increment,
output logic [DATA_WIDTH-1:0] read_data,
output logic empty
);

wire write_enable;
wire [ADDRESS_WIDTH-1:0] write_address;
wire [ADDRESS_WIDTH-1:0] write_address_gray_presync;
wire [ADDRESS_WIDTH-1:0] write_address_gray_postsync;
wire [ADDRESS_WIDTH-1:0] read_address;
wire [ADDRESS_WIDTH-1:0] read_address_gray_presync;
wire [ADDRESS_WIDTH-1:0] read_address_gray_postsync;

assign write_enable = (!full & write_increment);

dpram #(
.DATA_WIDTH(DATA_WIDTH),
.ADDRESS_WIDTH(ADDRESS_WIDTH)
) fifo_memory (
.clock(write_clock),
.write_address(write_address),
.write_data(write_data),
.write_enable(write_enable),
.read_address(read_address),
.read_data(read_data)
);

cdc_fifo_write_state #(
.ADDRESS_WIDTH(ADDRESS_WIDTH)
) writestate (
.clock(write_clock),
.reset(write_reset),
.increment(write_increment),
.read_address_gray(read_address_gray_postsync),
.write_address(write_address),
.write_address_gray(write_address_gray_presync),
.full(full)
);

cdc_fifo_read_state #(
.ADDRESS_WIDTH(ADDRESS_WIDTH)
) readstate (
.clock(read_clock),
.reset(read_reset),
.increment(read_increment),
.write_address_gray(write_address_gray_postsync),
.read_address(read_address),
.read_address_gray(read_address_gray_presync),
.empty(empty)
);

synchronizer #(
.WIDTH(ADDRESS_WIDTH)
) write_address_sync (
.clock(read_clock),
.reset(read_reset),
.in(write_address_gray_presync),
.out(write_address_gray_postsync)
);

synchronizer #(
.WIDTH(ADDRESS_WIDTH)
) read_address_sync (
.clock(write_clock),
.reset(write_reset),
.in(read_address_gray_presync),
.out(read_address_gray_postsync)
);

endmodule
40 changes: 40 additions & 0 deletions src/cdc_fifo_read_state.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module cdc_fifo_read_state #(
parameter ADDRESS_WIDTH = 4
) (
input logic clock,
input logic reset,
input logic increment,
input logic [ADDRESS_WIDTH-1:0] write_address_gray,

output logic [ADDRESS_WIDTH-1:0] read_address,
output logic [ADDRESS_WIDTH-1:0] read_address_gray,
output logic empty
);

logic [ADDRESS_WIDTH-1:0] write_address;

gray_to_binary #(
.WIDTH(ADDRESS_WIDTH)
) write_addr_decode (
.gray(write_address_gray),
.binary(write_address)
);

binary_to_gray #(
.WIDTH(ADDRESS_WIDTH)
) read_addr_encode (
.binary(read_address),
.gray(read_address_gray)
);

assign empty = (write_address == read_address);

always_ff @ (posedge clock or posedge reset) begin
if (reset) begin
read_address <= 0;
end else if (increment & !empty) begin
read_address <= read_address + 1;
end
end

endmodule
40 changes: 40 additions & 0 deletions src/cdc_fifo_write_state.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module cdc_fifo_write_state #(
parameter ADDRESS_WIDTH = 4
) (
input logic clock,
input logic reset,
input logic increment,
input logic [ADDRESS_WIDTH-1:0] read_address_gray,

output logic [ADDRESS_WIDTH-1:0] write_address,
output logic [ADDRESS_WIDTH-1:0] write_address_gray,
output logic full
);

assign full = (write_address + 1 == read_address);

logic [ADDRESS_WIDTH-1:0] read_address;

gray_to_binary #(
.WIDTH(ADDRESS_WIDTH)
) read_addr_decode (
.gray(read_address_gray),
.binary(read_address)
);

binary_to_gray #(
.WIDTH(ADDRESS_WIDTH)
) write_addr_encode (
.binary(write_address),
.gray(write_address_gray)
);

always_ff @ (posedge clock or posedge reset) begin
if (reset) begin
write_address <= 0;
end else if (increment & !full) begin
write_address <= write_address + 1;
end
end

endmodule
26 changes: 26 additions & 0 deletions src/dpram.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Dual-ported parameterized RAM module
module dpram #(
parameter DATA_WIDTH = 8,
parameter ADDRESS_WIDTH = 4
) (
input logic clock,

input logic [ADDRESS_WIDTH-1:0] write_address,
input logic [DATA_WIDTH-1:0] write_data,
input logic write_enable,

input logic [ADDRESS_WIDTH-1:0] read_address,
output logic [DATA_WIDTH-1:0] read_data
);

logic [DATA_WIDTH-1:0] memory [0:(1<<ADDRESS_WIDTH)-1];

assign read_data = memory[read_address];

always_ff @ (posedge clock) begin
if (write_enable) begin
memory[write_address] <= write_data;
end
end

endmodule
14 changes: 14 additions & 0 deletions src/gray_to_binary.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module gray_to_binary #(
parameter WIDTH = 8
) (
input logic [WIDTH-1:0] gray,
output logic [WIDTH-1:0] binary
);

always_comb begin
for (int i = 0; i < WIDTH; i++) begin
binary[i] = ^(gray >> i);
end
end

endmodule
27 changes: 0 additions & 27 deletions src/project.v

This file was deleted.

19 changes: 19 additions & 0 deletions src/synchronizer.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module synchronizer #(
parameter WIDTH = 1
) (
input logic clock,
input logic reset,
input logic [WIDTH-1:0] in,
output logic [WIDTH-1:0] out);

logic [WIDTH-1:0] data;

always_ff @ (posedge clock or posedge reset) begin
if (reset) begin
out <= 0;
data <= 0;
end else begin
{out, data} <= {data, in};
end
end
endmodule
62 changes: 62 additions & 0 deletions src/tt_um_pa1mantri_cdc_fifo.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 Your Name
* SPDX-License-Identifier: Apache-2.0
*/

`default_nettype none

module tt_um_pa1mantri_cdc_fifo (
input wire [7:0] ui_in, // Dedicated inputs
output wire [7:0] uo_out, // Dedicated outputs
input wire [7:0] uio_in, // IOs: Input path
output wire [7:0] uio_out, // IOs: Output path
output wire [7:0] uio_oe, // IOs: Enable path (active high: 0=input, 1=output)
input wire ena, // always 1 when the design is powered, so you can ignore it
input wire clk, // clock
input wire rst_n // reset_n - low to reset
);

// ui_in mappings

wire write_clock,write_increment,read_clock,read_increment;
wire [3:0]write_data;

assign write_clock = ui_in[0];
assign write_increment = ui_in[1];
assign read_clock = ui_in[2];
assign read_increment = ui_in[3];
assign write_data = ui_in[4];

//uo_out mappings

wire empty,full;
wire [3:0]read_data;

assign uo_out[0] = empty;
assign uo_out[1] = full;
assign uo_out[3:2] = 'b00;
assign uo_out[7:4] = read_data;

//uio_in mappings

wire read_reset,write_reset;

assign write_reset = !uio_in[0];
assign read_reset = !uio_in[1];

//Fifo instantiation

cdc_fifo #(
.DATA_WIDTH(4),
.ADDRESS_WIDTH(5)
) fifo (
.write_clock(write_clock),.write_reset(write_reset),.write_data(write_data),.write_increment(write_increment),.full(full),
.read_clock(read_clock),.read_reset(read_reset),.read_data(read_data),.read_increment(read_increment),.empty(empty)
);

// All output pins must be assigned. If not used, assign to 0.

assign uio_out =0;
assign uio_oe =0;

endmodule
Loading

0 comments on commit 90f8d9d

Please sign in to comment.