master
wtf 2 years ago
parent 4948e96692
commit 2576396abb

@ -0,0 +1 @@
dffram/

@ -13,41 +13,16 @@ $(info ..................................................)
# design and tech
unit = a2p

# 5% utilization
#[INFO PDN-0013] Inserting stdcell grid - grid
#Command terminated by signal 9
#export DIE_AREA = 0 0 10000 10000
#export CORE_AREA = 100 100 10000 10000
# 21% utilization
#Error: resize.tcl, 88 invalid command name "sta::max_slew_violation_count"
export DIE_AREA = 0 0 5000 5000
export CORE_AREA = 100 100 5000 5000

#export CORE_UTILIZATION = 100
#export CORE_ASPECT_RATIO = 1
#export CORE_MARGIN = 2

# a2o fu stuff
# keeps hierarchy of some cells even if flattening
#export PRESERVE_CELLS ?= tri_144x78_2r4w
# no flatten
#export SYNTH_NO_FLAT ?= 1
# don't optimize tri_144x78_2r4w
#export SYNTH_OPT_SELECTION ?= fu

#export PLACE_DENSITY ?= 0.80
# also set cycle time in constraint.sdc! derive it there from this?
#export ABC_CLOCK_PERIOD_IN_PS ?= 10000
#export ABC_DEFAULT_SCRIPT ?= 1

# fanout doesn't get adjusted to fix paths? or resizer not working
export DIE_AREA = 0.0 0.0 5200 4609.14
export CORE_AREA = 210 210 4990 4389.14

export ABC_CLOCK_PERIOD_IN_PS = 10000
export ABC_DRIVER_CELL = sky130_fd_sc_hd__buf_1
export ABC_LOAD_IN_FF = 3

export SYNTH_MAX_FANOUT ?= 32
export SYNTH_MAX_TRAN ?= 100

#wtf can't specify in resizer anymore?
#export RS_BUF_CELL ?= BUF_X4
#export RS_MAX_FO ?= 20

export REPORT_SLACK_MAX_PATHS ?= 100



@ -17,8 +17,7 @@ set_output_delay $output_delay_value -clock [get_clocks clk] [all_outputs]

# false paths
set_false_path -from [get_ports {reset}] -to [get_clocks clk]
#wtf - is this the dc write path?
set_false_path -from [get_nets {dBusWB_ACK}]
set_false_path -from [get_nets {a2p_wb/dbuswb_ack}]
set_false_path -from [get_nets {a2p_wb/dbuswb*}]

#wtf - is this the dc write path? lots of fo
#set_false_path -from [get_nets {dBusWB_ACK}]
#causes [ERROR STA-0467] unsupported object type Net

@ -0,0 +1,132 @@
# A2P for OpenLane/Carousel

* manually replace inferred mem with array macros; eventually make all arrays components (inferred for FPGA, phys for tech)

## Arrays to convert to DFFRAM

* IC (4K)

```
reg [21:0] ways_0_tags [0:127];
reg [31:0] ways_0_datas [0:1023];
```

* tag: 128x22b
* data: 1024x32b


* DC (4K)

```
reg [21:0] DC_DIR_tags [0:127];
reg [7:0] DC_DIR_data_symbol0 [0:1023];
reg [7:0] DC_DIR_data_symbol1 [0:1023];
reg [7:0] DC_DIR_data_symbol2 [0:1023];
reg [7:0] DC_DIR_data_symbol3 [0:1023];
```

* tag: 128x22b
* data(4): 1024x8b

* GPR

```
reg [31:0] RegFilePlugin_regFile [0:31] /* verilator public */ ;
```

* 32x32b, 3 read, 1 write

## Creating DFFRAM arrays

* ***REQUIRES DOCKER***

* github.com/efabless/openlane/blob/master/README.md

```
# clone OpenLane
# make full-pdk
```

* github.com/Cloud-V/DFFRAM

```
# clone DFFRam
export PDK_ROOT=/home/wtf/projects2/OpenLane/pdks

# optionally set design name for any builds; **doesn't set the output name**
# export FORCE_DESIGN_NAME=ram_32_32
```

### GPR

* need 3r1w and DFFRam creates 2r1w reg; so need 2 regs, or 3 32x32 RAM, or custom 3r script

* -v 1R1W not supported; is this basically the same as ram_32_32??

* multiple arrays will be instantiated in single gpr module; use parameter to select gen style

#### RAM

```
#export FORCE_DESIGN_NAME=ram_32x32
dffram.py -s 32x32 -p $PDK_ROOT
```

#### REG

* building block <pdk>:<scl>:<name> corresponds to platforms/<pdk>/<scl>/_building_blocks/<name>/model.v

```
#export FORCE_DESIGN_NAME=reg_32x32
dffram.py -s 32x32 -v 2R1W -p $PDK_ROOT -b sky130A:sky130_fd_sc_hd:rf
```

#### Tag Arrays, 4K

* need to make **decellerator** script to whack the extra 10 bits/word after place and then run rest of stuff

```
#export FORCE_DESIGN_NAME=ram_128x32
dffram.py -s 128x32 -p $PDK_ROOT
```

* OR try...

```
export FORCE_ACCEPT_SIZE=wtf
#export FORCE_DESIGN_NAME=ram_128x22
dffram.py -s 128x22 -p $PDK_ROOT
unset FORCE_ACCEPT_SIZE
```

#### Data Array, IC

```
#export FORCE_DESIGN_NAME=ram_1024x32
dffram.py -s 1024x32 -p $PDK_ROOT
```

#### Data Array, DC (4)

* DFFRam handles byte writes, so this is same as IC

```
#export FORCE_DESIGN_NAME=ram_1024x8
#dffram.py -s 1024x8 -p $PDK_ROOT
```

IC/DC arrays could be built using different subunits if better for layout/timing; 4KB = 128 lines x 32B.


## Updating core manually


* this is compiling components on non-generated paths...

```verilator --lint-only -Wno-fatal A2P_WB_RAM.v```

* add gpr.v and module to top; can use this to test on FPGA with ```EXPAND_TYPE=`INFERRED```




@ -1,4 +1,10 @@

# Test Site

* Litex platform for efabless caravel

* Core, I2C, UARTs, SPI, GPIO


#### https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/tree/master/flow

@ -40,5 +46,12 @@ https://github.com/The-OpenROAD-Project/OpenSTA/blob/35a3f1e4e3f148b30678f9455e6
* global placement (global_placement)
* detailed placement (legalize_placement)
* CTS (clock_tree_synthesis)
* global routing (fast_route) ***the unit hangs appear here in report_power***
* global routing (fast_route)
* detailed routing (detailed_route)


### replace inferred mems with DFFRAM components

(readme-dffram.md)

1. test with gpr using DFFRAMs and ic/dc dir/dat using small inferred mems (1 location)

@ -1 +0,0 @@
/home/wtf/projects/a2p/core/A2P_WB.v

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,54 @@
`include "defs.v"

module dcdata #(
parameter EXPAND_TYPE=`INFERRED,
parameter LINES=1024
) (
input clk,
input [9:0] rd_adr,
output [31:0] rd_dat,
input [3:0] wr_en,
input [9:0] wr_adr,
input [31:0] wr_dat
);

generate case (EXPAND_TYPE)

`INFERRED: begin
reg [7:0] dir0 [0:LINES-1];
reg [7:0] dir1 [0:LINES-1];
reg [7:0] dir2 [0:LINES-1];
reg [7:0] dir3 [0:LINES-1];
assign rd_dat = {dir3[rd_adr],dir2[rd_adr],dir1[rd_adr],dir0[rd_adr]};
always @ (posedge clk) begin
if(wr_en[0]) begin
dir0[wr_adr] <= wr_dat[7:0];
end
if(wr_en[1]) begin
dir1[wr_adr] <= wr_dat[15:8];
end
if(wr_en[2]) begin
dir2[wr_adr] <= wr_dat[23:16];
end
if(wr_en[3]) begin
dir3[wr_adr] <= wr_dat[31:24];
end
end
end
`DIR_RAM: begin
wire [9:0] adr;
assign adr = |wr_en ? wr_adr : rd_adr;
RAM1024 #() dir (
.CLK(clk),
.EN0('b1),
.A0(adr),
.Do0(rd_dat),
.WE0(wr_en),
.Di0(wr_dat)
);
end

endcase
endgenerate

endmodule

@ -0,0 +1,44 @@
`include "defs.v"

module dcdir #(
parameter EXPAND_TYPE=`INFERRED,
parameter LINES=128
) (
input clk,
input [6:0] rd_adr,
output [21:0] rd_dat,
input [3:0] wr_en,
input [6:0] wr_adr,
input [21:0] wr_dat
);

generate case (EXPAND_TYPE)

`INFERRED: begin
reg [21:0] dir [0:LINES-1];
assign rd_dat = dir[rd_adr];
always @ (posedge clk) begin
if(wr_en[0]) begin
dir[wr_adr] <= wr_dat;
end
end
end
`DIR_RAM: begin
wire [6:0] adr;
wire [31:0] dat;
assign adr = wr_en ? wr_adr : rd_adr;
assign rd_dat = dat[21:0];
RAM128 #() dir (
.CLK(clk),
.EN0('b1),
.A0(adr),
.Do0(dat),
.WE0(wr_en),
.Di0({'b0000000000, wr_dat})
);
end

endcase
endgenerate

endmodule

@ -0,0 +1,10 @@
// A2P defines

// Generation controls
`define INFERRED 0

`define GPR_2R1W 1
`define GPR_RAM 2
`define GPR_3R1W 3

`define DIR_RAM 1

@ -0,0 +1,75 @@
`include "defs.v"

module gpr #(
parameter EXPAND_TYPE=`INFERRED
) (
input clk,
input [4:0] rd_adr_0,
output [31:0] rd_dat_0,
input [4:0] rd_adr_1,
output [31:0] rd_dat_1,
input [4:0] rd_adr_2,
output [31:0] rd_dat_2,
input wr_en_0,
input [4:0] wr_adr_0,
input [31:0] wr_dat_0
);

generate case (EXPAND_TYPE)

`INFERRED: begin
reg [31:0] regFile [0:31] /* verilator public */ ;
assign rd_dat_0 = regFile[rd_adr_0];
assign rd_dat_1 = regFile[rd_adr_1];
assign rd_dat_2 = regFile[rd_adr_2];
always @ (posedge clk) begin
if(wr_en_0) begin
regFile[wr_adr_0] <= wr_dat_0;
end
end
end
`GPR_2R1W: begin
/* veeerilator is parsing this when not gen'd */
DFFRF_2R1W #() regFile01 (
.CLK(clk),
.RA(rd_adr_0),
.DA(rd_dat_0),
.RB(rd_adr_1),
.DB(rd_dat_1),
.RW(wr_adr_0),
.WE(wr_en_0),
.DW(wr_dat_0)
);
// should this be a ram_32x32? any other diffs between reg/ram besides multiple we vs extra port?
DFFRF_2R1W #() regFile23 (
.CLK(clk),
.RA(rd_adr_2),
.DA(rd_dat_2),
.RB('h0),
.DB(),
.RW(wr_adr_0),
.WE(wr_en_0),
.DW(wr_dat_0)
);
end
`GPR_3R1W: begin
reg_3r1w #() regFile (

);
end
`GPR_RAM: begin
ram_32x32 #() regFile0 (

);
ram_32x32 #() regFile1 (

);
ram_32x32 #() regFile2 (

);
end

endcase
endgenerate

endmodule

@ -0,0 +1,54 @@
`include "defs.v"

module icdata #(
parameter EXPAND_TYPE=`INFERRED,
parameter LINES=1024
) (
input clk,
input [9:0] rd_adr,
output [31:0] rd_dat,
input [3:0] wr_en,
input [9:0] wr_adr,
input [31:0] wr_dat
);

generate case (EXPAND_TYPE)

`INFERRED: begin
reg [7:0] dir0 [0:LINES-1];
reg [7:0] dir1 [0:LINES-1];
reg [7:0] dir2 [0:LINES-1];
reg [7:0] dir3 [0:LINES-1];
assign rd_dat = {dir3[rd_adr],dir2[rd_adr],dir1[rd_adr],dir0[rd_adr]};
always @ (posedge clk) begin
if(wr_en[0]) begin
dir0[wr_adr] <= wr_dat[7:0];
end
if(wr_en[1]) begin
dir1[wr_adr] <= wr_dat[15:8];
end
if(wr_en[2]) begin
dir2[wr_adr] <= wr_dat[23:16];
end
if(wr_en[3]) begin
dir3[wr_adr] <= wr_dat[31:24];
end
end
end
`DIR_RAM: begin
wire [9:0] adr;
assign adr = wr_en[0] ? wr_adr : rd_adr;
RAM1024 #() dir (
.CLK(clk),
.EN0('b1),
.A0(adr),
.Do0(rd_dat),
.WE0(wr_en),
.Di0(wr_dat)
);
end

endcase
endgenerate

endmodule

@ -0,0 +1,44 @@
`include "defs.v"

module icdir #(
parameter EXPAND_TYPE=`INFERRED,
parameter LINES=128
) (
input clk,
input [6:0] rd_adr,
output [21:0] rd_dat,
input [3:0] wr_en,
input [6:0] wr_adr,
input [21:0] wr_dat
);

generate case (EXPAND_TYPE)

`INFERRED: begin
reg [21:0] dir [0:LINES-1];
assign rd_dat = dir[rd_adr];
always @ (posedge clk) begin
if(wr_en[0]) begin
dir[wr_adr] <= wr_dat;
end
end
end
`DIR_RAM: begin
wire [6:0] adr;
wire [31:0] dat;
assign adr = wr_en ? wr_adr : rd_adr;
assign rd_dat = dat[21:0];
RAM128 #() dir (
.CLK(clk),
.EN0('b1),
.A0(adr),
.Do0(dat),
.WE0(wr_en),
.Di0({'b0000000000, wr_dat})
);
end

endcase
endgenerate

endmodule
Loading…
Cancel
Save