Skip to content

Commit

Permalink
1. add DelayChainMem2 which improved output behavior just like scfifo2.
Browse files Browse the repository at this point in the history
2. add Pid2 which merged parameter TS into others.
2. add dual mode (rotation & vectoring) cordic.
3. add some fundamental modules for streaming.
  • Loading branch information
loykylewong committed Aug 17, 2021
1 parent cdda35a commit 0aa2d4d
Show file tree
Hide file tree
Showing 9 changed files with 3,054 additions and 115 deletions.
38 changes: 38 additions & 0 deletions chapter4/delay_chain_mem.sv
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,44 @@ module DelayChainMem #(
endgenerate
endmodule

// improved output behavior (just like scfifo2)
module DelayChainMem2 #(
parameter DW = 8,
parameter LEN = 32
)(
input wire clk, en,
input wire [DW - 1 : 0] din,
output logic [DW - 1 : 0] dout
);
generate
if(LEN == 0) begin
assign dout = din;
end
else if(LEN == 1) begin
always_ff@(posedge clk) begin
if(en) dout <= din;
end
end
else begin
logic en_dly;
logic [DW-1:0] ram_out, ram_out_dly = '0;
assign dout = en_dly ? ram_out : ram_out_dly;
logic [$clog2(LEN) - 1 : 0] addr = '0;
SpRamRf #(DW, LEN) theRam(
.clk(clk), .addr(addr), .we(en), .din(din), .qout(ram_out)
);
always_ff@(posedge clk) begin
if(en) begin
if(addr < LEN - 2) addr <= addr + 1'b1;
else addr <= '0;
end
if(en_dly) ram_out_dly <= ram_out;
en_dly <= en;
end
end
endgenerate
endmodule

module TestDelayChainMem;
import SimSrcGen::*;
logic [7:0] a, y;
Expand Down
35 changes: 35 additions & 0 deletions chapter4/memory.sv
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ module SpRamRf #(
end
endmodule

module SpRamRa #( // asynchronous read
parameter DW = 8, WORDS = 256
)(
input wire clk,
input wire [$clog2(WORDS) - 1 : 0] addr,
input wire we,
input wire [DW - 1 : 0] din,
output logic [DW - 1 : 0] qout
);
logic [DW - 1 : 0] ram[WORDS];
always_ff@(posedge clk) begin
if(we) ram[addr] <= din;
end
assign qout = ram[addr];
endmodule

module SpRamWf #(
parameter DW = 8, WORDS = 256
)(
Expand Down Expand Up @@ -79,6 +95,25 @@ module SdpRamRf #(
end
endmodule

module SdpRamRa #(
parameter DW = 8, WORDS = 256
)(
input wire clk,
input wire [$clog2(WORDS) - 1 : 0] addr_a,
input wire wr_a,
input wire [DW - 1 : 0] din_a,
input wire [$clog2(WORDS) - 1 : 0] addr_b,
output logic [DW - 1 : 0] qout_b
);
logic [DW - 1 : 0] ram[WORDS];
always_ff@(posedge clk) begin
if(wr_a) begin
ram[addr_a] <= din_a;
end
end
assign qout_b = ram[addr_b];
endmodule

module DpRam #(
parameter DW = 8, WORDS = 256
)(
Expand Down
259 changes: 144 additions & 115 deletions chapter4/scfifo.sv
Original file line number Diff line number Diff line change
@@ -1,115 +1,144 @@
`ifndef __SCFIFO_SV__
`define __SCFIFO_SV__

`include "../common.sv"
`include "../chapter4/memory.sv"

`timescale 1ns/100ps
`default_nettype none

module TestScFifo;
import SimSrcGen::*;
logic clk;
initial GenClk(clk, 8, 10);
logic [7:0] din = '0, dout;
logic wr = '0, rd = '0;
logic [2:0] wc, rc, dc;
logic fu, em;
initial begin
for(int i = 0; i < 10; i++) begin
@(posedge clk) {wr, din} = {1'b1, 8'($random())};
end
@(posedge clk) wr = 1'b0;
for(int i = 0; i < 10; i++) begin
@(posedge clk) rd = 1'b1;
end
@(posedge clk) rd = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) {wr, din} = {1'b1, 8'($random())};
end
@(posedge clk) wr = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) rd = 1'b1;
end
@(posedge clk) rd = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) {wr, din} = {1'b1, 8'($random())};
end
@(posedge clk) wr = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) rd = 1'b1;
end
@(posedge clk) rd = 1'b0;
#10 $stop();
end
ScFifo2 #(8, 3) theFifo(clk, din, wr & ~fu, dout, rd & ~em, wc, rc, dc, fu, em);
endmodule

module ScFifo1 #(
parameter DW = 8,
parameter AW = 10
)(
input wire clk,
input wire [DW - 1 : 0] din,
input wire write,
output logic [DW - 1 : 0] dout,
input wire read,
output logic [AW - 1 : 0] wr_cnt = '0, rd_cnt = '0,
output logic [AW - 1 : 0] data_cnt,
output logic full, empty
);
localparam CAPACITY = 2**AW - 1;
always_ff@(posedge clk) begin
if(write) wr_cnt <= wr_cnt + 1'b1;
end
always_ff@(posedge clk) begin
if(read) rd_cnt <= rd_cnt + 1'b1;
end
assign data_cnt = wr_cnt - rd_cnt;
assign full = data_cnt == CAPACITY;
assign empty = data_cnt == 0;
SdpRamRf #(.DW(DW), .WORDS(2**AW)) theRam(
.clk(clk), .addr_a(wr_cnt), .wr_a(write),
.din_a(din), .addr_b(rd_cnt), .qout_b(dout)
);
endmodule

module ScFifo2 #(
parameter DW = 8,
parameter AW = 10
)(
input wire clk,
input wire [DW - 1 : 0] din,
input wire write,
output logic [DW - 1 : 0] dout,
input wire read,
output logic [AW - 1 : 0] wr_cnt = '0, rd_cnt = '0,
output logic [AW - 1 : 0] data_cnt,
output logic full, empty
);
localparam CAPACITY = 2**AW - 1;
always_ff@(posedge clk) begin
if(write) wr_cnt <= wr_cnt + 1'b1;
end
always_ff@(posedge clk) begin
if(read) rd_cnt <= rd_cnt + 1'b1;
end
assign data_cnt = wr_cnt - rd_cnt;
assign full = data_cnt == CAPACITY;
assign empty = data_cnt == 0;
logic rd_dly;
always_ff@(posedge clk) begin
rd_dly <= read;
end
logic [DW - 1 : 0] qout_b, qout_b_reg = '0;
always_ff@(posedge clk) begin
if(rd_dly) qout_b_reg <= qout_b;
end
SdpRamRf #(.DW(DW), .WORDS(2**AW)) theRam(
.clk(clk), .addr_a(wr_cnt), .wr_a(write),
.din_a(din), .addr_b(rd_cnt), .qout_b(qout_b)
);
assign dout = (rd_dly)? qout_b : qout_b_reg;
endmodule

`endif
`ifndef __SCFIFO_SV__
`define __SCFIFO_SV__

`include "../common.sv"
`include "../chapter4/memory.sv"

`timescale 1ns/100ps
`default_nettype none

module TestScFifo;
import SimSrcGen::*;
logic clk;
initial GenClk(clk, 8, 10);
logic [7:0] din = '0, dout;
logic wr = '0, rd = '0;
logic [2:0] wc, rc, dc;
logic fu, em;
initial begin
for(int i = 0; i < 10; i++) begin
@(posedge clk) {wr, din} = {1'b1, 8'($random())};
end
@(posedge clk) wr = 1'b0;
for(int i = 0; i < 10; i++) begin
@(posedge clk) rd = 1'b1;
end
@(posedge clk) rd = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) {wr, din} = {1'b1, 8'($random())};
end
@(posedge clk) wr = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) rd = 1'b1;
end
@(posedge clk) rd = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) {wr, din} = {1'b1, 8'($random())};
end
@(posedge clk) wr = 1'b0;
for(int i = 0; i < 5; i++) begin
@(posedge clk) rd = 1'b1;
end
@(posedge clk) rd = 1'b0;
#10 $stop();
end
ScFifo2 #(8, 3) theFifo(clk, din, wr & ~fu, dout, rd & ~em, wc, rc, dc, fu, em);
endmodule

module ScFifo1 #(
parameter DW = 8,
parameter AW = 10
)(
input wire clk,
input wire [DW - 1 : 0] din,
input wire write,
output logic [DW - 1 : 0] dout,
input wire read,
output logic [AW - 1 : 0] wr_cnt = '0, rd_cnt = '0,
output logic [AW - 1 : 0] data_cnt,
output logic full, empty
);
localparam CAPACITY = 2**AW - 1;
always_ff@(posedge clk) begin
if(write) wr_cnt <= wr_cnt + 1'b1;
end
always_ff@(posedge clk) begin
if(read) rd_cnt <= rd_cnt + 1'b1;
end
assign data_cnt = wr_cnt - rd_cnt;
assign full = data_cnt == CAPACITY;
assign empty = data_cnt == 0;
SdpRamRf #(.DW(DW), .WORDS(2**AW)) theRam(
.clk(clk), .addr_a(wr_cnt), .wr_a(write),
.din_a(din), .addr_b(rd_cnt), .qout_b(dout)
);
endmodule

module ScFifo2 #(
parameter DW = 8,
parameter AW = 10
)(
input wire clk,
input wire [DW - 1 : 0] din,
input wire write,
output logic [DW - 1 : 0] dout,
input wire read,
output logic [AW - 1 : 0] wr_cnt = '0, rd_cnt = '0,
output logic [AW - 1 : 0] data_cnt,
output logic full, empty
);
localparam CAPACITY = 2**AW - 1;
always_ff@(posedge clk) begin
if(write) wr_cnt <= wr_cnt + 1'b1;
end
always_ff@(posedge clk) begin
if(read) rd_cnt <= rd_cnt + 1'b1;
end
assign data_cnt = wr_cnt - rd_cnt;
assign full = data_cnt == CAPACITY;
assign empty = data_cnt == 0;
logic rd_dly;
always_ff@(posedge clk) begin
rd_dly <= read;
end
logic [DW - 1 : 0] qout_b, qout_b_reg = '0;
always_ff@(posedge clk) begin
if(rd_dly) qout_b_reg <= qout_b;
end
SdpRamRf #(.DW(DW), .WORDS(2**AW)) theRam(
.clk(clk), .addr_a(wr_cnt), .wr_a(write),
.din_a(din), .addr_b(rd_cnt), .qout_b(qout_b)
);
assign dout = (rd_dly)? qout_b : qout_b_reg;
endmodule

module ScFifoSA #( // output show-ahead(altera's term) or FWFT(xilinx's term)
parameter DW = 8,
parameter AW = 10
)(
input wire clk,
input wire [DW - 1 : 0] din,
input wire write,
output logic [DW - 1 : 0] dout,
input wire read,
output logic [AW - 1 : 0] wr_cnt = '0, rd_cnt = '0,
output logic [AW - 1 : 0] data_cnt,
output logic full, empty
);
localparam CAPACITY = 2**AW - 1;
always_ff@(posedge clk) begin
if(write) wr_cnt <= wr_cnt + 1'b1;
end
always_ff@(posedge clk) begin
if(read) rd_cnt <= rd_cnt + 1'b1;
end
assign data_cnt = wr_cnt - rd_cnt;
assign full = data_cnt == CAPACITY;
assign empty = data_cnt == 0;
SdpRamRa #(.DW(DW), .WORDS(2**AW)) theRam(
.clk(clk), .addr_a(wr_cnt), .wr_a(write),
.din_a(din), .addr_b(rd_cnt), .qout_b(dout)
);
endmodule

`endif
1 change: 1 addition & 0 deletions chapter5/iis.sv
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
`include "../common.sv"
`include "../chapter4/counter.sv"
`include "../chapter4/edge2en.sv"

`default_nettype none
`timescale 1ns/10ps

Expand Down
Loading

0 comments on commit 0aa2d4d

Please sign in to comment.