Skip to content

Commit 70b34d8

Browse files
committed
updated fifos
1 parent 2f3bc88 commit 70b34d8

30 files changed

+1967
-2007
lines changed
Loading
Loading
281 Bytes
Loading
Loading
420 Bytes
Loading

sequential-logic/memory/dual_port_ram_asynchronous/README.md

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Dual-port RAM is a type of computer memory that allows
1818
two separate devices to read and write data simultaneously.
1919
This is achieved by having two separate access ports, one for each device.
2020

21+
The B port will have precedence if data is written to both ports at the same time.
22+
2123
_I used
2224
[iverilog](https://github.com/JeffDeCola/my-cheat-sheets/tree/master/hardware/tools/simulation/iverilog-cheat-sheet)
2325
to simulate and
@@ -50,33 +52,41 @@ The
5052
behavioral model,
5153

5254
```verilog
53-
// DATA TYPES
54-
reg [7:0] mem [0:15];
55-
reg [3:0] address_register_A, address_register_B;
55+
// PARAMETERS
56+
parameter DATA_WIDTH = 8;
57+
parameter ADDR_WIDTH = 4;
58+
parameter MEM_DEPTH = 16;
5659
57-
// OUTPUT (THIS MAKES IT SYNCHRONOUS)
58-
assign data_out_A = mem[address_register_A];
59-
assign data_out_B = mem[address_register_B];
60+
// DATA TYPES
61+
reg [DATA_WIDTH-1:0] mem [0:MEM_DEPTH-1]; // RAM (16x8)
6062
61-
// RAM
63+
// PORT A
6264
// ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
6365
always @(posedge clk_A) begin
66+
// WRITE (DATA PASS)
6467
if (we_A) begin
6568
mem[addr_A] <= data_in_A;
69+
data_out_A <= data_in_A;
70+
// READ
6671
end else begin
67-
address_register_A <= addr_A;
72+
data_out_A <= mem[addr_A];
6873
end
6974
end
7075
71-
// RAM
76+
// PORT B - HAS PRECEDENCE FOR WRITE
7277
// ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
7378
always @(posedge clk_B) begin
79+
//WRITE (DATA PASS)
7480
if (we_B) begin
7581
mem[addr_B] <= data_in_B;
82+
data_out_B <= data_in_B;
83+
//READ
7684
end else begin
77-
address_register_B <= addr_B;
85+
data_out_B <= mem[addr_B];
7886
end
7987
end
88+
89+
endmodule
8090
```
8191

8292
## RUN (SIMULATE)
@@ -118,34 +128,34 @@ TEST START --------------------------------
118128
119129
| TIME(ns) | WE_A | ADDR_A | DATA_IN_A | DATA_OUT_A | WE_B | ADDR_B | DATA_IN_B | DATA_OUT_B |
120130
----------------------------------------------------------------------------------------------
121-
1 INIT | 12 | | 1 | 0000 | 00000000 | xxxxxxxx |
122-
1 INIT | 15 | 1 | 0000 | 00000000 | xxxxxxxx |
123-
2 WR_B | 26 | | 1 | 0001 | 11110011 | xxxxxxxx |
124-
2 WR_A | 35 | 1 | 0000 | 11110000 | xxxxxxxx |
125-
3 WR_B | 40 | | 1 | 0011 | 11001111 | xxxxxxxx |
126-
4 WR_B | 54 | | 1 | 1111 | 11101010 | xxxxxxxx |
127-
3 WR_A | 55 | 1 | 0001 | 00001111 | xxxxxxxx |
128-
5 RD_B | 68 | | 0 | 0001 | xxxxxxxx | 00001111 |
129-
4 WR_A | 75 | 1 | 1110 | 10101010 | xxxxxxxx |
131+
1 INIT | 12 | | 1 | 0000 | 00000000 | 00000000 |
132+
1 INIT_ | 15 | 1 | 0000 | 00000000 | 00000000 |
133+
2 WR_B | 26 | | 1 | 0001 | 11110011 | 11110011 |
134+
2 WR_A_ | 35 | 1 | 0000 | 11110000 | 11110000 |
135+
3 WR_B | 40 | | 1 | 0011 | 11001111 | 11001111 |
136+
4 WR_B | 54 | | 1 | 1110 | 11101010 | 11101010 |
137+
3 WR_A_ | 55 | 1 | 0001 | 00001111 | 00001111 |
138+
5 RD_B | 68 | | 0 | 1110 | xxxxxxxx | 11101010 |
139+
4 WR_A_ | 75 | 1 | 1110 | 10101010 | 10101010 |
130140
6 RD_B | 82 | | 0 | 0011 | xxxxxxxx | 11001111 |
131-
5 RD_A | 95 | 0 | 0000 | xxxxxxxx | 11110000 |
132-
7 RD_B | 96 | | 0 | 1111 | xxxxxxxx | 11101010 |
133-
8 RD_B | 110 | | 0 | 1110 | xxxxxxxx | 10101010 |
134-
6 RD_A | 115 | 0 | 0001 | xxxxxxxx | 00001111 |
141+
5 RD_A_ | 95 | 0 | 1110 | xxxxxxxx | 10101010 |
142+
7 RD_B | 96 | | 0 | 1111 | xxxxxxxx | xxxxxxxx |
143+
8 RD_B | 110 | | 0 | 0011 | xxxxxxxx | 11001111 |
144+
6 RD_A_ | 115 | 0 | 0001 | xxxxxxxx | 00001111 |
135145
9 RD_B | 124 | | 0 | 1001 | xxxxxxxx | xxxxxxxx |
136-
7 RD_A | 135 | 0 | 1110 | xxxxxxxx | 10101010 |
137-
10 RD_B | 138 | | 0 | 1111 | xxxxxxxx | 11101010 |
138-
11 WR_B | 152 | | 1 | 1111 | 00000000 | 00000000 |
139-
8 WR_A | 155 | 1 | 1001 | 00000111 | 10101010 |
140-
12 WR_B | 166 | | 1 | 0001 | 00011000 | 00000000 |
141-
9 WR_A | 175 | 1 | 1111 | 11111010 | 10101010 |
142-
13 RD_B | 180 | | 0 | 1111 | xxxxxxxx | 11111010 |
146+
7 RD_A_ | 135 | 0 | 0011 | xxxxxxxx | 11001111 |
147+
10 RD_B | 138 | | 0 | 1111 | xxxxxxxx | xxxxxxxx |
148+
11 WR_B | 152 | | 1 | 1111 | 01000000 | 01000000 |
149+
8 WR_A_ | 155 | 1 | 1001 | 00000111 | 00000111 |
150+
12 WR_B | 166 | | 1 | 0001 | 00011000 | 00011000 |
151+
9 WR_A_ | 175 | 1 | 1111 | 11111010 | 11111010 |
152+
13 RD_B | 180 | | 0 | 0001 | xxxxxxxx | 00011000 |
143153
14 RD_B | 194 | | 0 | 0001 | xxxxxxxx | 00011000 |
144-
10 WR_A | 195 | 1 | 1100 | 00000011 | 10101010 |
145-
11 WR_A | 215 | 1 | 0010 | 00001111 | 10101010 |
146-
12 RD_A | 235 | 0 | 0001 | xxxxxxxx | 00011000 |
147-
13 RD_A | 255 | 0 | 1111 | xxxxxxxx | 11111010 |
148-
14 RD_A | 275 | 0 | 0001 | xxxxxxxx | 00011000 |
154+
10 WR_A_ | 195 | 1 | 1100 | 00000011 | 00000011 |
155+
11 WR_A_ | 215 | 1 | 0010 | 00001111 | 00001111 |
156+
12 RD_A_ | 235 | 0 | 0001 | xxxxxxxx | 00011000 |
157+
13 RD_A_ | 255 | 0 | 0001 | xxxxxxxx | 00011000 |
158+
14 RD_A_ | 275 | 0 | 0001 | xxxxxxxx | 00011000 |
149159
150160
VECTORS_A: 14
151161
ERRORS_A: 0

sequential-logic/memory/dual_port_ram_asynchronous/dual_port_ram_asynchronous.v

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,50 @@
1-
// Dual-port asynchronous RAM using two different clocks.
1+
// Dual-port asynchronous RAM.
22

33
module dual_port_ram_asynchronous_behavioral(
4-
input clk_A, clk_B, // Clocks
5-
input we_A, we_B, // Write enable
6-
input [3:0] addr_A, addr_B, // Address
7-
input [7:0] data_in_A, data_in_B, // Data to write
8-
output [7:0] data_out_A, data_out_B); // Data to read
4+
input clk_A, // Clock A
5+
input clk_B, // Clock B
6+
// PORT A
7+
input we_A, // Write enable
8+
input [ADDR_WIDTH-1:0] addr_A, // Address
9+
input [DATA_WIDTH-1:0] data_in_A, // Data to write
10+
output reg [DATA_WIDTH-1:0] data_out_A, // Data to read
11+
// PORT B
12+
input we_B, // Write enable
13+
input [ADDR_WIDTH-1:0] addr_B, // Address
14+
input [DATA_WIDTH-1:0] data_in_B, // Data to write
15+
output reg [DATA_WIDTH-1:0] data_out_B); // Data to read
916

10-
// DATA TYPES
11-
reg [7:0] mem [0:15];
12-
reg [3:0] address_register_A, address_register_B;
17+
// PARAMETERS
18+
parameter DATA_WIDTH = 8;
19+
parameter ADDR_WIDTH = 4;
20+
parameter MEM_DEPTH = 16;
1321

14-
// OUTPUT (THIS MAKES IT SYNCHRONOUS)
15-
assign data_out_A = mem[address_register_A];
16-
assign data_out_B = mem[address_register_B];
22+
// DATA TYPES
23+
reg [DATA_WIDTH-1:0] mem [0:MEM_DEPTH-1]; // RAM (16x8)
1724

18-
// RAM
25+
// PORT A
1926
// ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
2027
always @(posedge clk_A) begin
28+
// WRITE (DATA PASS)
2129
if (we_A) begin
2230
mem[addr_A] <= data_in_A;
31+
data_out_A <= data_in_A;
32+
// READ
2333
end else begin
24-
address_register_A <= addr_A;
34+
data_out_A <= mem[addr_A];
2535
end
2636
end
2737

28-
// RAM
38+
// PORT B - HAS PRECEDENCE FOR WRITE
2939
// ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
3040
always @(posedge clk_B) begin
41+
//WRITE (DATA PASS)
3142
if (we_B) begin
3243
mem[addr_B] <= data_in_B;
44+
data_out_B <= data_in_B;
45+
//READ
3346
end else begin
34-
address_register_B <= addr_B;
47+
data_out_B <= mem[addr_B];
3548
end
3649
end
3750

sequential-logic/memory/dual_port_ram_asynchronous/dual_port_ram_asynchronous_tb.gtkw

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,37 @@
11
[*]
22
[*] GTKWave Analyzer v3.3.115 (w)1999-2023 BSI
3-
[*] Tue May 16 01:20:39 2023
3+
[*] Sun May 21 18:37:39 2023
44
[*]
55
[dumpfile] "/home/jeff/verilog/my-verilog-examples/sequential-logic/memory/dual_port_ram_asynchronous/dual_port_ram_asynchronous_tb.vcd"
6-
[dumpfile_mtime] "Tue May 16 01:15:44 2023"
7-
[dumpfile_size] 4303
6+
[dumpfile_mtime] "Sun May 21 18:34:00 2023"
7+
[dumpfile_size] 4339
88
[savefile] "/home/jeff/verilog/my-verilog-examples/sequential-logic/memory/dual_port_ram_asynchronous/dual_port_ram_asynchronous_tb.gtkw"
99
[timestart] 0
1010
[size] 1319 600
1111
[pos] 33266 32949
12-
*-15.929993 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
12+
*-15.929993 68000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
1313
[treeopen] DUAL_PORT_RAM_ASYNCHRONOUS_TB.
1414
[sst_width] 204
1515
[signals_width] 150
1616
[sst_expanded] 1
1717
[sst_vpaned_height] 152
1818
@28
1919
DUAL_PORT_RAM_ASYNCHRONOUS_TB.CLK_A
20+
@200
21+
-
22+
@28
2023
DUAL_PORT_RAM_ASYNCHRONOUS_TB.WE_A
21-
@23
22-
DUAL_PORT_RAM_ASYNCHRONOUS_TB.ADDR_A[3:0]
2324
@22
25+
DUAL_PORT_RAM_ASYNCHRONOUS_TB.ADDR_A[3:0]
2426
DUAL_PORT_RAM_ASYNCHRONOUS_TB.DATA_IN_A[7:0]
2527
DUAL_PORT_RAM_ASYNCHRONOUS_TB.DATA_OUT_A[7:0]
2628
@200
2729
-
2830
@28
2931
DUAL_PORT_RAM_ASYNCHRONOUS_TB.CLK_B
32+
@201
33+
-
34+
@28
3035
DUAL_PORT_RAM_ASYNCHRONOUS_TB.WE_B
3136
@22
3237
DUAL_PORT_RAM_ASYNCHRONOUS_TB.ADDR_B[3:0]

sequential-logic/memory/dual_port_ram_asynchronous/dual_port_ram_asynchronous_tb.v

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ module DUAL_PORT_RAM_ASYNCHRONOUS_TB;
8080

8181
initial begin
8282
// WAIT FOR TEST TO FINISH
83-
// THIS IS NOT PERFECT - I PROBABLY NEED TO FIX THIS FOR DIFFERENT CLOCK SPEEDS
84-
@(END_B);
85-
@(END_A);
83+
wait (END_A == 1'b1 && END_B == 1'b1);
8684
$display();
8785
$display(" VECTORS_A: %4d", VECTORCOUNT_A);
8886
$display(" ERRORS_A: %4d", ERRORS_A);
@@ -115,6 +113,7 @@ module DUAL_PORT_RAM_ASYNCHRONOUS_TB;
115113
end
116114

117115
end
116+
// $display("Waiting for b to finish");
118117

119118
end
120119

@@ -139,6 +138,7 @@ module DUAL_PORT_RAM_ASYNCHRONOUS_TB;
139138
end
140139

141140
end
141+
// $display("Waiting for a to finish");
142142

143143
end
144144

0 commit comments

Comments
 (0)