Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added base model of 7x64 #7

Merged
merged 1 commit into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions base_models/sky130_sram_1kbyte_1rw1r_32x256_8.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// OpenRAM SRAM model
// Words: 256
// Word size: 32
// Write size: 8

module sky130_sram_1kbyte_1rw1r_32x256_8(
`ifdef USE_POWER_PINS
vccd1,
vssd1,
`endif
// Port 0: RW
clk0,csb0,web0,wmask0,addr0,din0,dout0,
// Port 1: R
clk1,csb1,addr1,dout1
);

parameter NUM_WMASKS = 4 ;
parameter DATA_WIDTH = 32 ;
parameter ADDR_WIDTH = 8 ;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
// FIXME: This delay is arbitrary.
parameter DELAY = 3 ;
parameter VERBOSE = 1 ; //Set to 0 to only display warnings
parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary

`ifdef USE_POWER_PINS
inout vccd1;
inout vssd1;
`endif
input clk0; // clock
input csb0; // active low chip select
input web0; // active low write control
input [NUM_WMASKS-1:0] wmask0; // write mask
input [ADDR_WIDTH-1:0] addr0;
input [DATA_WIDTH-1:0] din0;
output [DATA_WIDTH-1:0] dout0;
input clk1; // clock
input csb1; // active low chip select
input [ADDR_WIDTH-1:0] addr1;
output [DATA_WIDTH-1:0] dout1;

reg csb0_reg;
reg web0_reg;
reg [NUM_WMASKS-1:0] wmask0_reg;
reg [ADDR_WIDTH-1:0] addr0_reg;
reg [DATA_WIDTH-1:0] din0_reg;
reg [DATA_WIDTH-1:0] dout0;

// All inputs are registers
always @(posedge clk0)
begin
csb0_reg = csb0;
web0_reg = web0;
wmask0_reg = wmask0;
addr0_reg = addr0;
din0_reg = din0;
#(T_HOLD) dout0 = 32'bx;
if ( !csb0_reg && web0_reg && VERBOSE )
$display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
if ( !csb0_reg && !web0_reg && VERBOSE )
$display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg);
end

reg csb1_reg;
reg [ADDR_WIDTH-1:0] addr1_reg;
reg [DATA_WIDTH-1:0] dout1;

// All inputs are registers
always @(posedge clk1)
begin
csb1_reg = csb1;
addr1_reg = addr1;
if (!csb0 && !web0 && !csb1 && (addr0 == addr1))
$display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1);
#(T_HOLD) dout1 = 32'bx;
if ( !csb1_reg && VERBOSE )
$display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]);
end

reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];

// Memory Write Block Port 0
// Write Operation : When web0 = 0, csb0 = 0
always @ (negedge clk0)
begin : MEM_WRITE0
if ( !csb0_reg && !web0_reg ) begin
if (wmask0_reg[0])
mem[addr0_reg][7:0] = din0_reg[7:0];
if (wmask0_reg[1])
mem[addr0_reg][15:8] = din0_reg[15:8];
if (wmask0_reg[2])
mem[addr0_reg][23:16] = din0_reg[23:16];
if (wmask0_reg[3])
mem[addr0_reg][31:24] = din0_reg[31:24];
end
end

// Memory Read Block Port 0
// Read Operation : When web0 = 1, csb0 = 0
always @ (negedge clk0)
begin : MEM_READ0
if (!csb0_reg && web0_reg)
dout0 <= #(DELAY) mem[addr0_reg];
end

// Memory Read Block Port 1
// Read Operation : When web1 = 1, csb1 = 0
always @ (negedge clk1)
begin : MEM_READ1
if (!csb1_reg)
dout1 <= #(DELAY) mem[addr1_reg];
end

endmodule
58 changes: 58 additions & 0 deletions base_models/tcam_7x64.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

module tcam7x64 (
input logic clk_i,
input logic csb_i,
input logic web_i,
input logic [3:0] wmask_i,
input logic [7:0] addr_i,
input logic [31:0] wdata_i,
output logic [63:0] rdata_o
);

//////////////////////
// Write address //
//////////////////////

logic [7:0] aw_addr;

assign aw_addr = {8{~web_i}} & addr_i;

////////////////////////////
// Read/Search address //
////////////////////////////

logic [7:0] ar_addr1;
logic [7:0] ar_addr2;

assign ar_addr1 = {1'b0, addr_i[6:0]}; // always read/search lower 128 rows
assign ar_addr2 = {1'b1, addr_i[6:0]} & {8{web_i}}; // always read/search upper 128 rows

/////////
// PMA //
/////////

logic [31:0] rdata_lower;
logic [31:0] rdata_upper;
logic [63:0] rdata;

assign rdata = {rdata_upper , rdata_lower};
assign rdata_o = rdata;

sky130_sram_1kbyte_1rw1r_32x256_8 u_vtb(

// Port 0: RW
.clk0 (clk_i),
.csb0 (csb_i),
.web0 (web_i),
.wmask0 (wmask_i),
.addr0 ((web_i ? ar_addr1: aw_addr)),
.din0 (wdata_i),
.dout0 (rdata_lower),
// Port 1: R
.clk1 (clk_i),
.csb1 (csb_i),
.addr1 (ar_addr2),
.dout1 (rdata_upper)
);

endmodule