Skip to content

Commit

Permalink
Update Scratchpad.h
Browse files Browse the repository at this point in the history
Separate Scratcpad into C++ class and SystemC module, add more checking for bank conflicts.
  • Loading branch information
Stuart-Swan authored and ben-k committed Sep 9, 2024
1 parent 6bde94b commit cb86770
Show file tree
Hide file tree
Showing 12 changed files with 639 additions and 80 deletions.
387 changes: 307 additions & 80 deletions cmod/include/Scratchpad.h

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cmod/regress_Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ DESIGNS ?= unittests/ArbiterModule \
unittests/LzdTop \
unittests/ReorderBufTop \
unittests/ScratchpadTop \
unittests/ScratchpadClassTop \
unittests/VectorUnit \
unittests/WHVCRouterTop \
unittests/axi/AxiAddWriteResp \
Expand Down
1 change: 1 addition & 0 deletions cmod/unittests/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
sim_*
*log
*.output.json
*.vcd
1 change: 1 addition & 0 deletions cmod/unittests/.p4ignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
sim_*
*log
*.output.json
*.vcd
18 changes: 18 additions & 0 deletions cmod/unittests/ScratchpadClassTop/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#
# Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License")
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

include ../unittests_Makefile

103 changes: 103 additions & 0 deletions cmod/unittests/ScratchpadClassTop/ScratchpadClassTop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SC_SCRATCHPAD_TOP_H
#define SC_SCRATCHPAD_TOP_H

#include <mc_connections.h>
#include "Scratchpad.h"
#include "auto_gen_fields.h"

// local Scratchpad "traits" class sets all of its characteristics
// Here the
// word_type is uint32
// number of banks is 16
// total capacity in words is 16 * 0x1000
typedef ScratchpadTraits<uint32, 16, 16 * 0x1000> local_mem;

// type declaration for input request to DUT
struct dut_in_t {
local_mem::addr_t addr;
local_mem::word_type data[local_mem::num_inputs];
bool is_load{0};

AUTO_GEN_FIELD_METHODS(dut_in_t, ( \
addr \
, data \
, is_load \
) )
};

#pragma hls_design top
class ScratchpadClassTop : public sc_module
{
public:
sc_in<bool> CCS_INIT_S1(clk);
sc_in<bool> CCS_INIT_S1(rst_bar);

Connections::In <dut_in_t> CCS_INIT_S1(in1);
Connections::Out<local_mem::word_type> CCS_INIT_S1(out1);

local_mem::mem_class_t scratchpad1;

SC_CTOR(ScratchpadClassTop) {
SC_THREAD(run);
sensitive << clk.pos();
async_reset_signal_is(rst_bar, false);
}

void run() {
in1.Reset();
out1.Reset();
wait();

#pragma hls_pipeline_init_interval 1
#pragma pipeline_stall_mode flush
while (1) {
// get the input request from the testbench
dut_in_t req1 = in1.Pop();

local_mem::scratchpad_req_t sp_req; // local scratchpad request type

// copy incoming request to scratchpad request
#pragma hls_unroll yes
for (int i=0 ; i < local_mem::num_inputs; i++)
sp_req.set(i, req1.addr + i, req1.data[i]);

if (req1.is_load)
{
// if it is a load (i.e. read) operation, get the read data from the RAM
local_mem::base_rsp_t rsp = scratchpad1.load(sp_req);

// compute MAC
local_mem::word_type sum=0;
#pragma hls_unroll yes
for (int i=0; i < local_mem::num_inputs; i++) {
sum += rsp.data[i] * req1.data[i];
}

// Push out the sum
out1.Push(sum);
}
else
{
// if it is a store (i.e. write) operation, write the data to the RAM
scratchpad1.store(sp_req);
}
}
}
};

#endif
165 changes: 165 additions & 0 deletions cmod/unittests/ScratchpadClassTop/testbench.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "ScratchpadClassTop.h"
#include <mc_scverify.h>

class Top : public sc_module
{
public:
CCS_DESIGN(ScratchpadClassTop) CCS_INIT_S1(dut1);

sc_clock clk;
SC_SIG(bool, rst_bar);
local_mem::word_type* ref_mem;
bool* ref_mem_valid;
unsigned match_count{0};
unsigned mismatch_count{0};

Connections::Combinational<local_mem::word_type> CCS_INIT_S1(out1);
Connections::Combinational<dut_in_t> CCS_INIT_S1(in1);

SC_CTOR(Top)
: clk("clk", 1, SC_NS, 0.5,0,SC_NS,true) {
sc_object_tracer<sc_clock> trace_clk(clk);

ref_mem = new local_mem::word_type[local_mem::capacity_in_words];
ref_mem_valid = new bool[local_mem::capacity_in_words];

for (unsigned i=0; i < local_mem::capacity_in_words; i++)
ref_mem_valid[i] = 0;

dut1.clk(clk);
dut1.rst_bar(rst_bar);
dut1.out1(out1);
dut1.in1(in1);

SC_CTHREAD(reset, clk);

SC_THREAD(stim);
sensitive << clk.posedge_event();
async_reset_signal_is(rst_bar, false);

SC_THREAD(resp);
sensitive << clk.posedge_event();
async_reset_signal_is(rst_bar, false);
}

struct my_fifo_t : public tlm::tlm_fifo<uint64> {
my_fifo_t() : tlm_fifo(32) {}
};

my_fifo_t read_fifo1;
static const int test_count = 1000;


void stim() {
CCS_LOG("Stimulus started");
in1.ResetWrite();
wait();

dut_in_t dut_in1;

CCS_LOG("addr_width bank_sel_width capacity_in_words: " << std::dec << local_mem::addr_width << " " << local_mem::bank_sel_width << " " << local_mem::capacity_in_words);

// Write random coefficient values to ascending memory locations:
unsigned addr = 0;
for (unsigned r = 0; r < local_mem::words_per_bank; r++) {
dut_in1.is_load = 0;
dut_in1.addr = addr;
for (unsigned i=0; i < local_mem::num_inputs; i++) {
dut_in1.data[i] = rand();
++addr;
ref_mem_valid[addr] = 1;
ref_mem[addr] = dut_in1.data[i];
}
in1.Push(dut_in1);
}

// Do multiply-accumulate operations using coefficients in scratchpad and input data
// weights sent here.
// starting address for the coefficient reads is randomly selected here
for (unsigned r = 0; r < test_count; r++) {
unsigned addr;
while (1) {
addr = rand() & (( 1 << local_mem::addr_width ) - 1);
if (addr < local_mem::capacity_in_words - local_mem::num_inputs)
break;
}
dut_in1.is_load = 1;
dut_in1.addr = addr;

// compute MAC for ref model checking here:
unsigned sum = 0;
for (unsigned i=0; i < local_mem::num_inputs; i++) {
dut_in1.data[i] = rand();
++addr;
sum += dut_in1.data[i] * ref_mem[addr];
}

in1.Push(dut_in1);
read_fifo1.put(sum);
}

wait(100);
CCS_LOG("MATCH COUNT: " << std::dec << match_count);
CCS_LOG("MISMATCH COUNT: " << std::dec << mismatch_count);
sc_stop();
}

void resp() {
out1.ResetRead();
wait();

while (1) {
for (unsigned i=0; i < test_count; i++) {
uint64 ref = read_fifo1.get();
local_mem::word_type rsp = out1.Pop();
if (ref != rsp) {
++mismatch_count;
}
else {
++match_count;
}
}
}
}

void reset() {
rst_bar.write(0);
wait(5);
rst_bar.write(1);
wait();
}
};

int sc_main(int argc, char **argv)
{
sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING);
sc_report_handler::set_actions(SC_ERROR, SC_DISPLAY);
//sc_trace_file *trace_file_ptr = sc_trace_static::setup_trace_file("trace");

Top top("top");
//trace_hierarchy(&top, trace_file_ptr);
sc_start();
if (sc_report_handler::get_count(SC_ERROR) > 0) {
std::cout << "Simulation FAILED" << std::endl;
return -1;
}
std::cout << "Simulation PASSED" << std::endl;
return 0;
}

1 change: 1 addition & 0 deletions hls/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
*.output.json
*.csv
catapult_cache
*.vcd
1 change: 1 addition & 0 deletions hls/.p4ignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
*.output.json
*.csv
catapult_cache
*.vcd
1 change: 1 addition & 0 deletions hls/regress_Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ DESIGNS ?= \
unittests/LzdTop \
unittests/ReorderBufTop \
unittests/ScratchpadTop \
unittests/ScratchpadClassTop \
unittests/VectorUnit \
MemModel \
ConnectionsRecipes/Adder \
Expand Down
18 changes: 18 additions & 0 deletions hls/unittests/ScratchpadClassTop/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License")
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

ROOT := ../../..

include $(ROOT)/hls/hls_Makefile
22 changes: 22 additions & 0 deletions hls/unittests/ScratchpadClassTop/go_hls.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License")
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

source ../../nvhls_exec.tcl

proc nvhls::usercmd_post_assembly {} {
upvar TOP_NAME TOP_NAME
directive set /${TOP_NAME}/.../banks.bank.*:rsc -match glob -MAP_TO_MODULE ram_nangate-45nm-separate_beh.RAM_separateRW
}

nvhls::run

0 comments on commit cb86770

Please sign in to comment.