Skip to content

Commit d012b2a

Browse files
Merge branch 'main' into user-guide-ToC
2 parents 2dc4679 + f37bb87 commit d012b2a

24 files changed

+423
-286
lines changed

.github/workflows/rpe_test.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,11 @@ jobs:
9393
if: ${{ matrix.os != 'ubuntu-22.04' }}
9494
run: npm test
9595

96-
- name: E2E Playwright tests on Linux latest & MacOS
96+
- name: E2E Playwright tests on Linux latest
9797
if: ${{ matrix.os == 'ubuntu-latest' }}
9898
run: |
99-
cp -rf Raptor/etc backend
99+
cp -rvf Raptor/etc backend
100+
ls -l backend/etc/device.xml
100101
npm run compile && xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npx playwright test
101102
102103
- name: cat RPE log

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
# Rapid Power Estimator
66

7+
![RPE Logo](imgs/rpelogo.png)
8+
79
Rapid Power Estimation Tool allows you to estimate power consumption at various stages of your design cycle. It simplifies the input of design information through intuitive wizards and delivers comprehensive power and thermal data analysis.
810

911
## Pre-requisite

backend/restapi_server.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#
55
import argparse
66
import os
7+
import signal
78
import sys
89
from flask import Flask, request, jsonify
910
from flasgger import Swagger
@@ -34,7 +35,7 @@ def main():
3435
args = parser.parse_args()
3536

3637
# setup app logger
37-
log_setup(filename=args.logfile, max_bytes=args.maxbytes*1024, backup_count=args.backupcount)
38+
log_setup(filename=args.logfile, max_bytes=args.maxbytes * 1024, backup_count=args.backupcount)
3839

3940
# Check if the device_file exists
4041
if os.path.exists(args.device_file) == False:
@@ -54,7 +55,7 @@ def main():
5455
"swagger": "2.0",
5556
"info": {
5657
"title": "RPE Backend API",
57-
"description": "The RPE Backend APIs which consumed by the RPE frontend for power and thermal estimation of the Rapid Silicon devices.",
58+
"description": "The RPE Backend APIs which are consumed by the RPE frontend for power and thermal estimation of the Rapid Silicon devices.",
5859
"version": "0.1.0"
5960
}
6061
}
@@ -81,6 +82,25 @@ def after_request(response):
8182
log(f"{request.method} {request.url} {response.status_code} - DONE")
8283
return response
8384

85+
# Graceful shutdown function
86+
def shutdown_server():
87+
log("Shutting down server...")
88+
func = request.environ.get('werkzeug.server.shutdown')
89+
if func is not None:
90+
func()
91+
else:
92+
log("Server shutdown function not found.", RsLogLevel.ERROR)
93+
94+
# Signal handler for smooth shutdown
95+
def signal_handler(signal_received, frame):
96+
log(f"Signal {signal_received} received, initiating shutdown...")
97+
shutdown_server()
98+
sys.exit(0)
99+
100+
# Register the signal handler for SIGINT (Ctrl+C) and SIGTERM
101+
signal.signal(signal.SIGINT, signal_handler)
102+
signal.signal(signal.SIGTERM, signal_handler)
103+
84104
# log app server started
85105
log("App server is running...")
86106

backend/submodule/peripherals.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,15 @@ class GpioStandard(RsEnum):
7070
SSTL_3_3V_Class_I = 10, "SSTL 3.3V Class-I"
7171
SSTL_3_3V_Class_II = 11, "SSTL 3.3V Class-II"
7272

73+
#class N22_RISC_V_Clock(RsEnum):
74+
# PLL_233MHz = 0, "PLL (233 MHz)"
75+
# BOOT_Clock_40MHz = 1, "BOOT CLK (40 MHz)"
76+
# RC_OSC_50MHz = 2, "RC OSC (50 MHz)"
77+
7378
class N22_RISC_V_Clock(RsEnum):
74-
PLL_233MHz = 0, "PLL (233 MHz)"
75-
BOOT_Clock_40MHz = 1, "BOOT CLK (40 MHz)"
76-
RC_OSC_50MHz = 2, "RC OSC (50 MHz)"
79+
PLL_233MHz = 0, "PLL"
80+
BOOT_Clock_40MHz = 1, "BOOT CLK"
81+
RC_OSC_50MHz = 2, "RC OSC"
7782

7883
class Port_Activity(RsEnum):
7984
IDLE = 0, "Idle"

cleanup.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
1-
const isWindows = process.platform === 'win32';
1+
const os = require('os');
2+
const platform = os.platform();
23

34
const kill = (process) => {
4-
if (isWindows) {
5-
const kill = require('tree-kill');
6-
kill(process.pid);
7-
} else {
8-
process.kill('SIGINT');
9-
}
5+
console.log(`Attempting to kill process with PID: ${process.pid}`);
6+
const { spawn } = require('child_process');
7+
if (platform === 'win32') {
8+
// used taskkill for Windows to terminate the process tree
9+
const taskKill = spawn('taskkill', ['/PID', process.pid, '/T', '/F']);
10+
taskKill.on('close', (code) => {
11+
if (code === 0) {
12+
console.log('Process killed successfully on Windows.');
13+
} else {
14+
console.error(`taskkill failed with exit code: ${code}`);
15+
}
16+
});
17+
} else if (platform === 'darwin' || platform === 'linux') {
18+
const taskKill = spawn('kill', ['-9', process.pid]);
19+
taskKill.on('close', (code) => {
20+
if (code === 0) {
21+
console.log('Process killed successfully on Unix.');
22+
} else {
23+
console.error(`taskkill failed with exit code: ${code}`);
24+
}
25+
});
26+
} else {
27+
try {
28+
process.kill('SIGINT');
29+
console.log('SIGINT sent to process');
30+
} catch (error) {
31+
console.error(`Failed to send SIGINT: ${error.message}`);
32+
}
33+
}
1034
};
1135

1236
module.exports = { kill };

docs/source/user_guide/FPGA_index.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Clocking
1414
The clocking section is located on the top left of the FPGA input section.
1515

1616
.. image:: figures/FPGA-figures-clocking-clocking_selected.JPG
17+
1718
Selecting the clocking section will display an empty table at the botton of the screen, click the "+Add" button above the table to fill out clock information.
1819

1920
.. image:: figures/FPGA-figures-clocking-input_clock_info.JPG
@@ -132,4 +133,5 @@ Selecting the IO section displays an empty table, click the "Add" button above t
132133
12. Enter input enable rate - default is **50%** for inputs
133134
13. Enter output enable rate - default is **50%** for outputs
134135
14. select synchronization option - default is **none** for signals that are already clocked and don't cross domains
135-
15. Enter toggle rate - Industry standard default is **12.5%**
136+
15. Enter toggle rate - Industry standard default is **12.5%**
137+

imgs/rpeicon.png

8.05 KB
Loading

imgs/rpelogo.png

22.1 KB
Loading

imgs/rpesidebar.png

59.4 KB
Loading

main.js

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const log = require('electron-log');
1010
const config = require('./rpe.config.json');
1111
const { kill } = require('./cleanup');
1212
const { openProjectRequest, saveProjectRequest } = require('./projectFile');
13+
const now = new Date();
1314

1415
const logFormat = '[{h}:{i}:{s}.{ms}] [{level}] {text}';
1516
log.transports.console.format = logFormat;
@@ -154,6 +155,13 @@ if (!isDev) {
154155
});
155156
log.transports.console.level = false; // silent console
156157
}
158+
159+
console.log(`
160+
=================================================
161+
RPE - Session Start at ${now.toLocaleString()}
162+
=================================================
163+
`);
164+
157165
const template = [
158166
{
159167
label: 'File',
@@ -212,19 +220,36 @@ const template = [
212220
label: 'Help',
213221
submenu: [
214222
{
223+
label: 'User Guide',
215224
role: 'help',
216225
click: async () => {
217-
await shell.openExternal('https://github.com/os-fpga/rapid_power_estimator/blob/main/README.md');
226+
await shell.openExternal('https://rapidpowerestimator.readthedocs.io/en/latest/');
227+
},
228+
},
229+
{
230+
label: 'About',
231+
click: () => {
232+
// dynamically reading package.json
233+
const packagePath = path.join(__dirname, 'package.json');
234+
const packageData = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
235+
236+
const message = `${packageData.build.productName}\nVersion: ${packageData.version}\nAuthor: ${packageData.author}\nCopyright: ${packageData.build.copyright}`;
237+
238+
dialog.showMessageBox(mainWindow, {
239+
type: 'info',
240+
title: packageData.build.productName,
241+
message: message,
242+
});
218243
},
219244
},
220245
],
221-
},
246+
},
222247
];
223248

224249
const startFlaskServer = () => {
225250
let apiServer;
226251
const RestAPIscript = path.join(__dirname, 'backend/restapi_server.py');
227-
const restAPIexe = path.join(app.getAppPath(), '..', '..', 'backend', 'restapi_server.exe');
252+
const restAPIexe = path.join(app.getAppPath(), '..', '..', 'backend', 'restapi_server.exe', 'restapi_server.exe');
228253

229254
const args = [
230255
'--port', store.get('port'),
@@ -267,6 +292,7 @@ const createWindow = () => {
267292
mainWindow = new BrowserWindow({
268293
width: 1400,
269294
height: 800,
295+
icon: `${__dirname}/imgs/rpeicon.png`,
270296
webPreferences: {
271297
preload: path.join(app.getAppPath(), 'preload.js'),
272298
nodeIntegration: true,
@@ -289,7 +315,7 @@ const createWindow = () => {
289315
store.set('device_xml', arg.device_xml);
290316
store.set('useDefaultFile', arg.useDefaultFile);
291317

292-
serverProcess.kill();
318+
kill(serverProcess);
293319

294320
app.relaunch();
295321
app.quit();
@@ -317,7 +343,15 @@ app.whenReady().then(() => {
317343
});
318344
});
319345

320-
app.on('window-all-closed', () => {
346+
app.on("before-quit", function () {
321347
kill(serverProcess);
348+
})
349+
350+
app.on('window-all-closed', () => {
351+
console.log(`
352+
=================================================
353+
RPE - Session closed at ${now.toLocaleString()}
354+
=================================================
355+
`);
322356
if (process.platform !== 'darwin') app.quit();
323357
});

package.json

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"test:playwright": "npx playwright test",
1414
"postinstall": "electron-builder install-app-deps",
1515
"pack": "electron-builder --dir",
16-
"dist": "pyinstaller --distpath backend --workpath dist -y --clean -n restapi_server.exe --onefile backend/restapi_server.py && webpack --mode production && electron-builder -p never"
16+
"dist": "pyinstaller --distpath backend --workpath dist -y --clean -n restapi_server.exe backend/restapi_server.py && webpack --mode development && electron-builder -p never"
1717
},
1818
"build": {
1919
"appId": "org.rapidsilicon.rapid_power_estimator",
@@ -28,6 +28,7 @@
2828
"node_modules/**/*",
2929
"package.json",
3030
"cleanup.js",
31+
"imgs/*",
3132
"projectFile.js"
3233
],
3334
"directories": {
@@ -38,6 +39,10 @@
3839
"from": "backend/restapi_server.exe",
3940
"to": "./backend/restapi_server.exe"
4041
},
42+
{
43+
"from": "backend/etc/devices",
44+
"to": "./backend/etc/devices"
45+
},
4146
{
4247
"from": "backend/etc/device.xml",
4348
"to": "./backend/etc/device.xml"
@@ -62,13 +67,13 @@
6267
}
6368
],
6469
"publisherName": "Rapid Silicon, Inc.",
65-
"icon": "RPE_icon.png",
70+
"icon": "imgs/rpeicon.png",
6671
"artifactName": "${name}_windows_installer.${ext}"
6772
},
6873
"nsis": {
6974
"oneClick": false,
7075
"allowToChangeInstallationDirectory": true,
71-
"installerSidebar": "imgs/rpesidebar.bmp"
76+
"installerSidebar": "imgs/rpesidebar.png"
7277
},
7378
"mac": {
7479
"category": "public.app-category.productivity",
@@ -89,6 +94,7 @@
8994
"@babel/core": "^7.23.9",
9095
"@babel/preset-env": "^7.24.4",
9196
"@babel/preset-react": "^7.24.1",
97+
"@playwright/test": "^1.48.1",
9298
"@testing-library/jest-dom": "^6.5.0",
9399
"@testing-library/react": "^14.3.1",
94100
"@testing-library/user-event": "^14.5.2",
@@ -109,7 +115,6 @@
109115
"react-test-renderer": "^18.3.1",
110116
"style-loader": "^3.3.4",
111117
"webpack": "^5.90.1",
112-
"@playwright/test": "^1.48.1",
113118
"webpack-cli": "^5.1.4"
114119
},
115120
"dependencies": {
@@ -131,4 +136,4 @@
131136
"type": "git",
132137
"url": "https://github.com/os-fpga/rapid_power_estimator.git"
133138
}
134-
}
139+
}

src/components/ModalWindows/BramModal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function BramModal({
3434
{
3535
fieldType: FieldType.number,
3636
id: 'bram_used',
37-
text: 'Used',
37+
text: 'BRAMs Used',
3838
value: defaultValue.bram_used,
3939
},
4040
{

src/components/ModalWindows/ClockingModal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function ClockingModal({
3838
{
3939
fieldType: FieldType.number,
4040
id: 'frequency',
41-
text: 'Frequency',
41+
text: 'Frequency (Hz)',
4242
value: defaultValue.frequency,
4343
},
4444
{

src/components/ModalWindows/DspModal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function DspModal({
3030
{
3131
fieldType: FieldType.number,
3232
id: 'number_of_multipliers',
33-
text: 'XX',
33+
text: 'Number of Multipliers',
3434
value: defaultValue.number_of_multipliers,
3535
},
3636
{

src/components/Tables/BramTable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ function BramTable({ device, update, notify }) {
158158
];
159159

160160
const mainTableHeader = [
161-
'', 'Action', 'En', 'Name/Hierarchy', 'BRAM Type', 'Used', 'Port', 'Clock', 'Width', 'Write En', 'Read En',
161+
'', 'Action', 'En', 'Name/Hierarchy', 'BRAM Type', 'BRAMs Used', 'Port', 'Clock', 'Width', 'Write En', 'Read En',
162162
'Toggle Rate', 'Clock Freq', 'RAM Depth', 'O/P Sig Rate', 'Block Power', 'Intc. Power', '%',
163163
];
164164

src/components/Tables/ClockingTable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function ClockingTable({ device, update, notify }) {
2929
const sources = GetOptions('Source');
3030

3131
const mainTableHeader = [
32-
'', 'Action', 'En', 'Description', 'Source', 'Port/Signal name', 'Frequency', 'Clock Control', 'Fanout',
32+
'', 'Action', 'En', 'Description', 'Source', 'Port/Signal name', 'Frequency (Hz)', 'Clock Control', 'Fanout',
3333
'Block Power', 'Intc. Power', '%',
3434
];
3535

src/components/Tables/DspTable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ function DspTable({ device, update, notify }) {
106106
];
107107

108108
const mainTableHeader = [
109-
'', 'Action', 'En', 'Name/Hierarchy', 'XX', 'DSP Mode', { className: 'no-wrap', text: 'A-W' }, { className: 'no-wrap', text: 'B-W' },
109+
'', 'Action', 'En', 'Name/Hierarchy', 'No. of Multipliers', 'DSP Mode', { className: 'no-wrap', text: 'A-W' }, { className: 'no-wrap', text: 'B-W' },
110110
'Clock', 'Pipeline', 'T-Rate',
111111
'Block Used', 'Clock Freq', 'O/P Sig Rate', 'Block Power', 'Intc. Power', '%',
112112
];

0 commit comments

Comments
 (0)