systemC示例
main.cpp
#include <memory>
using namespace std;
#include "top.h"
int sc_main(int i, char *av[])
{
// 关闭关于 IEEE 1666 标准中过时特性的警告
sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING);
cout << "sc main start at " << sc_time_stamp() << endl;
std::shared_ptr<Top> top = make_shared<Top>("top");
sc_start(200, SC_NS);
cout << "sc main end at " << sc_time_stamp() << endl;
return 0;
}
top.h
#include <systemc.h>
#include "dcu_interface.h"
SC_MODULE(Top)
{
SC_CTOR(Top)
{
dcu_interface_ = std::make_shared<Dcu_Interface>("dcu_Interface");
SC_THREAD(DcuDataHandle);
}
public:
std::shared_ptr<Dcu_Interface> dcu_interface_;
void SetDcuRegValue();
void SetDcuHbusRam();
void SendFeatureMapStartSignal(uint32_t start_flag);
void SendDataHandleStartSignal();
void DcuDataHandle();
};
top.cpp
#include "top.h"
void Top::SetDcuRegValue()
{
uint64_t fin_step_h = 1;
uint64_t fin_parallel_h = (uint64_t)1 << 32;
uint64_t reg_data = fin_step_h + fin_parallel_h;
dcu_interface_->DcuRegWrite(0x0, (uint8_t *)®_data, 8);
uint64_t fin_h = 4;
uint64_t fin_w = (uint64_t)4 << 32;
reg_data = fin_h + fin_w;
dcu_interface_->DcuRegWrite(0x8, (uint8_t *)®_data, 8);
uint64_t fin_c = 4;
uint64_t kernel_num = (uint64_t)4 << 32;
reg_data = fin_c + kernel_num;
dcu_interface_->DcuRegWrite(0x10, (uint8_t *)®_data, 8);
uint64_t kernel_size = 64;
uint64_t weight_buf_load_en = (uint64_t)1 << 32;
reg_data = kernel_size + weight_buf_load_en;
dcu_interface_->DcuRegWrite(0x18, (uint8_t *)®_data, 8);
uint64_t bias_buf_load_en = 1;
uint64_t scale_buf_load_en = (uint64_t)1 << 32;
reg_data = bias_buf_load_en + scale_buf_load_en;
dcu_interface_->DcuRegWrite(0x20, (uint8_t *)®_data, 8);
uint64_t weight_addr = 0x10000;
uint64_t bias_addr = (uint64_t)0x20000 << 32;
reg_data = weight_addr + bias_addr;
dcu_interface_->DcuRegWrite(0x28, (uint8_t *)®_data, 8);
uint64_t scale_addr = 0x30000;
uint64_t fin_bit_mode = (uint64_t)1 << 32;
reg_data = scale_addr + fin_bit_mode;
dcu_interface_->DcuRegWrite(0x30, (uint8_t *)®_data, 8);
uint64_t fin_sign = 1;
uint64_t dcu_en = (uint64_t)1 << 32;
reg_data = fin_sign + dcu_en;
dcu_interface_->DcuRegWrite(0x38, (uint8_t *)®_data, 8, 1);
}
void Top::SetDcuHbusRam()
{
std::array<uint8_t, 256> weight;
std::fill(weight.begin(), weight.end(), 1);
dcu_interface_->HbusMemWrite(0x10000, weight.data(), 256);
std::array<int16_t, 4> bias;
std::fill(bias.begin(), bias.end(), 50);
dcu_interface_->HbusMemWrite(0x20000, (uint8_t *)bias.data(), 8);
std::array<uint8_t, 4> scale;
std::fill(scale.begin(), scale.end(), 2);
dcu_interface_->HbusMemWrite(0x30000, scale.data(), 4, 1);
}
void Top::DcuDataHandle()
{
while (1)
{
SetDcuRegValue();
SetDcuHbusRam();
wait(30, SC_NS);
SendFeatureMapStartSignal(1);
wait(5, SC_NS);
SendFeatureMapStartSignal(0);
wait(5, SC_NS);
SendFeatureMapStartSignal(1);
wait(5, SC_NS);
SendFeatureMapStartSignal(0);
wait(5, SC_NS);
SendFeatureMapStartSignal(1);
wait(5, SC_NS);
SendFeatureMapStartSignal(0);
wait(10, SC_NS);
SendDataHandleStartSignal();
wait(90, SC_NS);
}
}
void Top::SendFeatureMapStartSignal(uint32_t start_flag)
{
dcu_interface_->array_->feature_map_write_flag_.write(start_flag);
}
void Top::SendDataHandleStartSignal()
{
dcu_interface_->dcu_->dcu_start_event_.notify();
}
dcu_interface.h
#pragma once
#include <systemc.h>
#include <map>
#include <vector>
#include "array.h"
#include "dcu.h"
#include "mem_interface.h"
#include "post.h"
#include "reg_read_interface.h"
#include "reg_write_interface.h"
using namespace sc_core;
class Dcu_Interface : public RegWrite_Interface, public RegRead_Interface, public Mem_Interface, public sc_module
{
SC_HAS_PROCESS(Dcu_Interface); // 声明模块支持进程
public:
Dcu_Interface(sc_module_name name);
~Dcu_Interface();
std::shared_ptr<Dcu> dcu_;
std::shared_ptr<Array> array_;
std::shared_ptr<Post> post_;
sc_event feature_map_event_;
sc_event dcu_result_event_;
virtual void DcuRegWrite(uint32_t addr, uint8_t* val, uint32_t size, uint8_t end_flag = 0);
virtual void DcuRegRead(uint32_t addr, uint8_t* val, uint32_t size);
virtual bool HbusMemWrite(uint32_t addr, uint8_t* val, uint32_t size, uint8_t end_flag = 0);
virtual bool HbusMemRead(uint32_t addr, uint8_t* val, uint32_t size);
virtual void HbusMemReset();
private:
sc_signal<uint32_t> dcu_reg_addr_;
sc_signal<uint64_t> dcu_reg_data_;
sc_fifo<uint8_t> feature_map_fifo_;
sc_fifo<int16_t> dcu_result_fifo_;
};
dcu_interface.cpp
#include "dcu_interface.h"
#include <chrono>
#include <thread>
Dcu_Interface::Dcu_Interface(sc_module_name name) : feature_map_fifo_(64)
{
dcu_ = std::make_shared<Dcu>("dcu", this);
array_ = std::make_shared<Array>("array", this);
array_->feature_map_out_(feature_map_fifo_);
dcu_->feature_map_in_(feature_map_fifo_);
post_ = std::make_shared<Post>("post", this);
dcu_->dcu_result_out_(dcu_result_fifo_);
post_->dcu_result_in_(dcu_result_fifo_);
dcu_->reg_write_addr_in_(dcu_reg_addr_);
dcu_->reg_write_data_in_(dcu_reg_data_);
}
Dcu_Interface::~Dcu_Interface()
{
}
void Dcu_Interface::DcuRegRead(uint32_t addr, uint8_t* val, uint32_t size)
{
dcu_->Read(addr, val, size);
wait(5, SC_NS);
}
void Dcu_Interface::DcuRegWrite(uint32_t addr, uint8_t* val, uint32_t size, uint8_t end_flag)
{
dcu_->Write(addr, val, size);
wait(5, SC_NS);
if (1 == end_flag)
{
dcu_->reg_write_end_event_.notify();
}
}
bool Dcu_Interface::HbusMemRead(uint32_t addr, uint8_t* val, uint32_t size)
{
if (addr + size <= RAM_SIZE)
{
memcpy(val, this->hbus_ram_ + addr, size);
wait(5, SC_NS);
return true;
}
else
{
cout << "addr + size = " << addr + size << "over range ram size" << endl;
return false;
}
}
bool Dcu_Interface::HbusMemWrite(uint32_t addr, uint8_t* val, uint32_t size, uint8_t end_flag)
{
if (addr + size <= RAM_SIZE)
{
memcpy(this->hbus_ram_ + addr, val, size);
wait(5, SC_NS);
if (1 == end_flag)
{
dcu_->hbus_load_event_.notify();
}
return true;
}
else
{
cout << "addr + size = " << addr + size << "over range ram size" << endl;
return false;
}
}
void Dcu_Interface::HbusMemReset()
{
memset(hbus_ram_, 0, RAM_SIZE);
}
dcu.h
#pragma once
#include "dcu_param.h"
class Dcu_Interface;
class Dcu : public sc_module
{
SC_HAS_PROCESS(Dcu); // 声明模块支持进程
public:
Dcu(sc_module_name name, Dcu_Interface* dcu_interface);
sc_in<uint32_t> reg_write_addr_in_;
sc_in<uint64_t> reg_write_data_in_;
sc_fifo_in<uint8_t> feature_map_in_;
std::vector<uint8_t> feature_map_;
std::vector<int16_t> dcu_result_;
sc_fifo_out<int16_t> dcu_result_out_;
sc_event reg_write_end_event_;
sc_event hbus_load_event_;
sc_event dcu_start_event_;
/* 写dcu寄存器 */
uint32_t Write(uint32_t addr, uint8_t* val, uint32_t size);
/* 读dcu寄存器 */
uint32_t Read(uint32_t addr, uint8_t* val, uint32_t size);
private:
Dcu_Interface* dcu_interface_;
/* dcu table */
DcuTableUnion dcu_table_union_ = {};
/*转化后的feature_map数据*/
std::array<int8_t, DCU_MAX_FEATURE_MAP_NUM * DCU_MAX_PARALLEL_H> feature_map_ex_;
/*feature map 并行度解析后的数据*/
std::array<std::array<int8_t, DCU_MAX_FEATURE_MAP_NUM>, DCU_MAX_PARALLEL_H> feature_map_after_parallel_parse_;
/*处理过程中的数据 */
std::array<int32_t, DCU_OUTPUT_CHANNEL_MAX_NUM> middle_result_;
/*最终结果 */
std::array<int16_t, DCU_OUTPUT_CHANNEL_MAX_NUM> final_result_;
/* weight数据 */
std::array<int8_t, DCU_WEIGHT_RAM_SIZE> dcu_pe_weight_mem_;
/* bias数据 */
std::array<int16_t, DCU_BIAS_RAM_SIZE> dcu_bias_mem_;
/* scale值 */
std::array<uint8_t, DCU_SCALE_RAM_SIZE> dcu_scale_mem_;
uint32_t work_step_;
/* 寄存器地址有效性检查 */
uint32_t AddrValid(uint32_t addr);
/* 接收feature map */
void RecvFeatureMap();
/* 加载hbus ram数据 */
void LoadHbusMem();
/* 启动dcu数据处理 */
void DcuDataProcessStart();
/* 初始化参数 */
uint32_t DcuParamsInit();
/* 打印并检查寄存器参数 */
uint32_t DcuParamsPrint();
/* feature map h/w转化 */
uint32_t DcuFeatureMapEx();
/* feature map数据并行度解析*/
uint32_t ParallelFeatureMapParse();
/* PE阵列计算 */
uint32_t DcuPECalc();
/* 输出结果加bias */
uint32_t DcuPEResultAddBias();
/* 输出结果移位*/
uint32_t DcuAddBiasResultMovebits();
/* dcu结果发送*/
uint32_t SendDcuResult();
/* 一次滑窗数据处理流程结束,重置状态 */
uint32_t WorkDone();
};
dcu.cpp
#include "dcu.h"
#include "dcu_interface.h"
/* 构造函数 */
Dcu::Dcu(sc_module_name name, Dcu_Interface *dcu_interface) : dcu_interface_(dcu_interface)
{
SC_THREAD(LoadHbusMem);
SC_METHOD(RecvFeatureMap);
sensitive << dcu_interface->feature_map_event_;
dont_initialize();
SC_THREAD(DcuDataProcessStart);
}
/**
* @description:寄存器地址有效性检查
* @param {uint64_t&} addr 寄存器地址
* @return {uint64_t} 执行流程是否异常 {RT_ERROR = 0, RT_OK = 1}
* @author: duyu
* @Date: 2023-04-07 17:17:19
*/
uint32_t Dcu::AddrValid(uint32_t addr)
{
uint32_t ret = RT_OK;
if ((addr >= DCU_REG_START) && (addr <= DCU_REG_END))
{
ret = RT_OK;
}
else
{
ret = RT_ERROR;
}
return ret;
}
/**
* @description:写寄存器
* @param {uint64_t} in_addr 寄存器地址
* @param {uint8_t*} in_data 寄存器数据
* @param {uint64_t} in_size 数据大小
* @return 无
* @author: duyu
* @Date: 2024-01-26 17:17:19
*/
uint32_t Dcu::Write(uint32_t addr, uint8_t *val, uint32_t size)
{
uint32_t ret = RT_OK;
uint32_t offset = 0;
if (AddrValid(addr))
{
offset = addr - DCU_REG_START;
for (uint32_t i = 0; i < size; i++)
{
dcu_table_union_.reg_8[offset + i] = val[i];
}
}
else
{
ret = RT_ERROR;
}
cout << "dcu reg write addr = 0x" << hex << addr << " at " << sc_time_stamp() << endl;
return ret;
}
/**
* @description:读寄存器
* @param {uint64_t} in_addr 寄存器地址
* @param {uint8_t*} out_data 寄存器数据
* @param {uint64_t} in_size 数据大小
* @return 无
* @author: duyu
* @Date: 2024-01-26 17:17:19
*/
uint32_t Dcu::Read(uint32_t addr, uint8_t *val, uint32_t size)
{
uint32_t ret = RT_OK;
uint32_t offset = 0;
/*地址有效性检查*/
if (AddrValid(addr))
{
offset = addr - DCU_REG_START;
for (uint32_t i = 0; i < size; i++)
{
val[i] = dcu_table_union_.reg_8[offset + i];
}
}
else
{
ret = RT_ERROR;
}
cout << "dcu reg read addr = 0x" << hex << addr << " at " << sc_time_stamp() << endl;
return ret;
}
void Dcu::LoadHbusMem()
{
while (1)
{
wait(hbus_load_event_ & reg_write_end_event_);
/* weight */
if (dcu_table_union_.dcu_table.weight_buf_load_en)
{
cout << "weight load start at " << sc_time_stamp() << endl;
dcu_interface_->HbusMemRead(dcu_table_union_.dcu_table.weight_addr, (uint8_t *)dcu_pe_weight_mem_.data(),
dcu_table_union_.dcu_table.kernel_size * dcu_table_union_.dcu_table.kernel_num);
cout << "weight load end at " << sc_time_stamp() << endl;
}
/* bias */
if (dcu_table_union_.dcu_table.bias_buf_load_en)
{
cout << "bias load start at " << sc_time_stamp() << endl;
dcu_interface_->HbusMemRead(dcu_table_union_.dcu_table.bias_addr, (uint8_t *)dcu_bias_mem_.data(),
dcu_table_union_.dcu_table.kernel_num * sizeof(int16_t));
cout << "bias load end at " << sc_time_stamp() << endl;
}
/* scale */
if (dcu_table_union_.dcu_table.scale_buf_load_en)
{
cout << "scale load start at " << sc_time_stamp() << endl;
dcu_interface_->HbusMemRead(dcu_table_union_.dcu_table.scale_addr, dcu_scale_mem_.data(), dcu_table_union_.dcu_table.kernel_num);
cout << "scale load end at " << sc_time_stamp() << endl;
}
}
}
void Dcu::RecvFeatureMap()
{
uint8_t feature_map = 0;
static uint32_t recv_feature_map_num = 0;
while (feature_map_in_.num_available() > 0)
{
feature_map = feature_map_in_.read();
// cout << "feature map: " << dec << (int)feature_map << endl;
feature_map_.push_back(feature_map);
}
recv_feature_map_num++;
cout << "num:" << recv_feature_map_num << " recv feature map at " << sc_time_stamp() << endl;
}
void Dcu::DcuDataProcessStart()
{
uint32_t ret = 0;
wait(dcu_start_event_);
DcuParamsInit();
cout << "data process start at " << sc_time_stamp() << endl;
while (1)
{
if (dcu_table_union_.dcu_table.dcu_en)
{
switch (work_step_)
{
case 0: /* 并行阵列解析 */
wait(10, SC_NS);
ret = ParallelFeatureMapParse();
if (RT_OK == ret)
{
work_step_ = 1;
cout << "feature map parse end at " << sc_time_stamp() << endl;
}
break;
case 1: /* PE阵列计算 */
wait(10, SC_NS);
ret = DcuPECalc();
if (RT_OK == ret)
{
work_step_ = 2;
cout << "pe cal end at " << sc_time_stamp() << endl;
}
break;
case 2: /* 加bias */
wait(10, SC_NS);
ret = DcuPEResultAddBias();
if (RT_OK == ret)
{
work_step_ = 3;
cout << "add bias end at " << sc_time_stamp() << endl;
}
break;
case 3: /* 移位 */
wait(10, SC_NS);
ret = DcuAddBiasResultMovebits();
if (RT_OK == ret)
{
work_step_ = 4;
cout << "movebit end at " << sc_time_stamp() << endl;
}
break;
case 4: /* 数据发送 */
wait(10, SC_NS);
ret = SendDcuResult();
if (RT_OK == ret)
{
work_step_ = 5;
cout << "dcu send result at " << sc_time_stamp() << endl;
}
break;
case 5: /* 置位 */
wait(10, SC_NS);
ret = WorkDone();
if (RT_OK == ret)
{
work_step_ = 6;
cout << "data process end at " << sc_time_stamp() << endl;
return;
}
break;
default:
break;
}
}
}
}
/**
* @description:初始化运行参数
* @param {*}
* @return {*}
* @author: duyu
* @Date: 2023-01-26 09:17:16
*/
uint32_t Dcu::DcuParamsInit()
{
uint32_t ret = RT_OK;
work_step_ = 0;
/* mem */
std::fill(feature_map_ex_.begin(), feature_map_ex_.end(), 0);
for (uint32_t i = 0; i < DCU_MAX_PARALLEL_H; ++i)
{
for (uint32_t j = 0; j < DCU_MAX_FEATURE_MAP_NUM; ++j)
{
feature_map_after_parallel_parse_[i][j] = 0;
}
}
std::fill(middle_result_.begin(), middle_result_.end(), 0);
std::fill(final_result_.begin(), final_result_.end(), 0);
/* 寄存器参数校验和打印 */
DcuParamsPrint();
return ret;
}
uint32_t Dcu::DcuParamsPrint()
{
uint32_t ret = RT_OK;
/* print */
// cout << "fin_step_h = 0x" << std::hex << dcu_table_union_.dcu_table.fin_step_h << endl;
// cout << "fin_parallel_h = 0x" << std::hex << dcu_table_union_.dcu_table.fin_parallel_h << endl;
// cout << "fin_h = 0x" << std::hex << dcu_table_union_.dcu_table.fin_h << endl;
// cout << "fin_w = 0x" << std::hex << dcu_table_union_.dcu_table.fin_w << endl;
// cout << "fin_c = 0x" << std::hex << dcu_table_union_.dcu_table.fin_c << endl;
// cout << "kernel_num = 0x" << std::hex << dcu_table_union_.dcu_table.kernel_num << endl;
// cout << "kernel_size = 0x" << std::hex << dcu_table_union_.dcu_table.kernel_size << endl;
// cout << "weight_buf_load_en = 0x" << std::hex << dcu_table_union_.dcu_table.weight_buf_load_en << endl;
// cout << "bias_buf_load_en = 0x" << std::hex << dcu_table_union_.dcu_table.bias_buf_load_en << endl;
// cout << "scale_buf_load_en = 0x" << std::hex << dcu_table_union_.dcu_table.scale_buf_load_en << endl;
// cout << "weight_addr = 0x" << std::hex << dcu_table_union_.dcu_table.weight_addr << endl;
// cout << "bias_addr = 0x" << std::hex << dcu_table_union_.dcu_table.bias_addr << endl;
// cout << "scale_addr = 0x" << std::hex << dcu_table_union_.dcu_table.scale_addr << endl;
// cout << "fin_bit_mode = 0x" << std::hex << dcu_table_union_.dcu_table.fin_bit_mode << endl;
// cout << "fin_sign = 0x" << std::hex << dcu_table_union_.dcu_table.fin_sign << endl;
// cout << "dcu_en = 0x" << std::hex << dcu_table_union_.dcu_table.dcu_en << endl;
return ret;
}
/**
* @description:并行模式下feature map数据解析
* @return 执行流程是否异常 {RT_ERROR = 0, RT_OK = 1}
* @author: duyu
* @Date: 2023-04-07 17:17:19
*/
uint32_t Dcu::ParallelFeatureMapParse()
{
uint32_t ret = RT_OK;
/* hw转化*/
DcuFeatureMapEx();
/* feature map并行度解析*/
if (1 == dcu_table_union_.dcu_table.fin_parallel_h)
{
memcpy(feature_map_after_parallel_parse_[0].data(), feature_map_ex_.data(), dcu_table_union_.dcu_table.kernel_size);
}
else if ((dcu_table_union_.dcu_table.fin_parallel_h > 1) && (dcu_table_union_.dcu_table.fin_parallel_h <= DCU_MAX_PARALLEL_H))
{
for (uint32_t i = 0; i < dcu_table_union_.dcu_table.fin_parallel_h; i++)
{
memcpy(feature_map_after_parallel_parse_[i].data(),
feature_map_ex_.data() +
i * dcu_table_union_.dcu_table.fin_step_h * dcu_table_union_.dcu_table.fin_w * dcu_table_union_.dcu_table.fin_c,
dcu_table_union_.dcu_table.kernel_size);
}
}
return ret;
}
/**
* @description:写feature map数据h到w切换
* @param {uint64_t} feature_map_data_in_64bit dacfifo_sort拼接成的64bit数据
* @return {uint32_t} 执行流程是否异常 {RT_ERROR = 0, RT_OK = 1}
* @author: duyu
* @Date: 2023-04-07 17:17:19
*/
uint32_t Dcu::DcuFeatureMapEx()
{
uint32_t ret = RT_OK;
/* hw方向转化*/
if (!feature_map_.empty())
{
for (uint32_t fin_w = 0; fin_w < dcu_table_union_.dcu_table.fin_w; fin_w++)
{
for (uint32_t fin_h = 0; fin_h < dcu_table_union_.dcu_table.fin_h; fin_h++)
{
memcpy(feature_map_ex_.data() + (fin_h * dcu_table_union_.dcu_table.fin_w + fin_w) * dcu_table_union_.dcu_table.fin_c,
feature_map_.data() + (fin_h + dcu_table_union_.dcu_table.fin_h * fin_w) * dcu_table_union_.dcu_table.fin_c,
dcu_table_union_.dcu_table.fin_c);
}
}
/* 去掉缓存中的feature map*/
feature_map_.erase(feature_map_.begin(), feature_map_.begin() + dcu_table_union_.dcu_table.fin_h * dcu_table_union_.dcu_table.fin_w *
dcu_table_union_.dcu_table.fin_c);
}
else
{
ret = RT_ERROR;
}
return ret;
}
/**
* @description:PE阵列计算
* @param 无
* @return {uint32_t} 执行流程是否异常 {RT_ERROR = 0, RT_OK = 1}
* @author: duyu
* @Date: 2023-04-07 17:17:19
*/
uint32_t Dcu::DcuPECalc()
{
uint32_t ret = RT_OK;
int32_t mul_result = 0;
for (uint32_t parallel_index = 0; parallel_index < dcu_table_union_.dcu_table.fin_parallel_h; parallel_index++)
{
for (uint32_t output_index = 0; output_index < dcu_table_union_.dcu_table.kernel_num; output_index++)
{
for (uint32_t feature_map_index = 0; feature_map_index < dcu_table_union_.dcu_table.kernel_size; feature_map_index++)
{
mul_result = static_cast<int32_t>(feature_map_after_parallel_parse_[parallel_index][feature_map_index] *
dcu_pe_weight_mem_[output_index * dcu_table_union_.dcu_table.kernel_size + feature_map_index]);
middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + output_index] += mul_result;
}
// cout << "pe cal result: " << dec << middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + output_index] << endl;
}
}
return ret;
}
/**
* @description:输出结果加bias
* @param 无
* @return {uint32_t} 执行流程是否异常 {RT_ERROR = 0, RT_OK = 1}
* @author: duyu
* @Date: 2023-04-07 17:17:19
*/
uint32_t Dcu::DcuPEResultAddBias()
{
uint32_t ret = RT_OK;
/* 加bias*/
for (uint32_t parallel_index = 0; parallel_index < dcu_table_union_.dcu_table.fin_parallel_h; parallel_index++)
{
for (uint32_t middle_result_index = 0; middle_result_index < dcu_table_union_.dcu_table.kernel_num; middle_result_index++)
{
middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] =
middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] + dcu_bias_mem_[middle_result_index];
// cout << "add bias result: " << dec << middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index]
// << endl;
}
}
return ret;
}
/**
* @description:输出结果移位
* @param 无
* @return {uint32_t} 执行流程是否异常 {RT_ERROR = 0, RT_OK = 1}
* @author: duyu
* @Date: 2023-04-07 17:17:19
*/
uint32_t Dcu::DcuAddBiasResultMovebits()
{
uint32_t ret = RT_OK;
/* 移位*/
for (uint32_t parallel_index = 0; parallel_index < dcu_table_union_.dcu_table.fin_parallel_h; parallel_index++)
{
for (uint32_t middle_result_index = 0; middle_result_index < dcu_table_union_.dcu_table.kernel_num; middle_result_index++)
{
middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] =
middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] >>
dcu_scale_mem_[middle_result_index];
/* 饱和截断*/
if (middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] >= 0)
{
if (middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] > 0x7fff)
{
final_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] = 0x7fff;
}
else
{
final_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] =
middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index];
}
}
else
{
if (middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] < 0xffff8000)
{
final_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] = 0x8000;
}
else
{
final_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index] =
middle_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index];
}
}
dcu_result_.push_back(final_result_[parallel_index * dcu_table_union_.dcu_table.kernel_num + middle_result_index]);
}
}
return ret;
}
/**
* @description:工作流程结束
* @param {*}
* @return {*}
* @author: duyu
* @Date: 2023-04-07 17:17:19
*/
uint32_t Dcu::WorkDone()
{
uint32_t ret = RT_OK;
/* mem */
std::fill(feature_map_ex_.begin(), feature_map_ex_.end(), 0);
for (uint32_t i = 0; i < DCU_MAX_PARALLEL_H; ++i)
{
for (uint32_t j = 0; j < DCU_MAX_FEATURE_MAP_NUM; ++j)
{
feature_map_after_parallel_parse_[i][j] = 0;
}
}
std::fill(middle_result_.begin(), middle_result_.end(), 0);
std::fill(final_result_.begin(), final_result_.end(), 0);
return ret;
}
uint32_t Dcu::SendDcuResult()
{
uint32_t ret = RT_OK;
sc_time time(10, SC_NS);
while (!dcu_result_.empty())
{
dcu_result_out_.write(dcu_result_.front());
dcu_result_.erase(dcu_result_.begin());
}
dcu_interface_->dcu_result_event_.notify(time);
return ret;
}
array.h
#pragma once
#include <systemc.h>
class Dcu_Interface;
class Array : public sc_module
{
public:
SC_HAS_PROCESS(Array); // 声明模块支持进程和线程
sc_fifo_out<uint8_t> feature_map_out_;
sc_signal<bool> feature_map_write_flag_;
void SendFeatureMap();
Array(sc_module_name name, Dcu_Interface* dcu_interface) : dcu_interface_(dcu_interface)
{
SC_METHOD(SendFeatureMap);
sensitive_pos << feature_map_write_flag_;
dont_initialize();
}
private:
Dcu_Interface* dcu_interface_;
};
array.cpp
#include "array.h"
#include "dcu_interface.h"
void Array::SendFeatureMap()
{
static uint32_t send_feature_map_num = 0;
sc_time time(10, SC_NS);
for (uint i = 0; i < 64; i++)
{
feature_map_out_.write(i);
}
dcu_interface_->feature_map_event_.notify(time);
send_feature_map_num++;
cout << "num:" << send_feature_map_num << " send feature map at " << sc_time_stamp() << endl;
}
post.h
#pragma once
#include <systemc.h>
class Dcu_Interface;
class Post : public sc_module
{
public:
SC_HAS_PROCESS(Post); // 声明模块支持进程和线程
Post(sc_module_name name, Dcu_Interface* dcu_interface);
sc_fifo_in<int16_t> dcu_result_in_;
std::vector<int16_t> dcu_result_;
/* 接收dcu 计算结果 */
void RecvDcuResult();
private:
Dcu_Interface* dcu_interface_;
};
post.cpp
#include "post.h"
#include "dcu_interface.h"
Post::Post(sc_module_name name, Dcu_Interface* dcu_interface) : dcu_interface_(dcu_interface)
{
SC_METHOD(RecvDcuResult);
sensitive << dcu_interface_->dcu_result_event_;
dont_initialize();
}
void Post::RecvDcuResult()
{
int16_t dcu_data = 0;
while (dcu_result_in_.num_available() > 0)
{
dcu_data = dcu_result_in_.read();
cout << "recv dcu data: " << dec << (int)dcu_data << endl;
dcu_result_.push_back(dcu_data);
}
cout << "post recv dcu data at " << sc_time_stamp() << endl;
}
feature_map_interface.h
#include <systemc.h>
#include <vector>
using namespace std;
class Feature_Map_Interface : virtual public sc_interface
{
/*走非指令通路 写buffer接口 tia_scale/comp数据 */
virtual void FeatureMapWrite(uint8_t* data, uint32_t size) = 0;
};
mem_interface.h
#include <systemc.h>
#include <vector>
using namespace std;
constexpr uint32_t RAM_SIZE = 256 * 1024;
class Mem_Interface : virtual public sc_interface
{
public:
/*走非指令通路 写buffer接口 tia_scale/comp数据 */
virtual bool HbusMemWrite(uint32_t addr, uint8_t* val, uint32_t size, uint8_t end_flag = 0) = 0;
virtual bool HbusMemRead(uint32_t addr, uint8_t* val, uint32_t size) = 0;
virtual void HbusMemReset() = 0;
uint8_t hbus_ram_[RAM_SIZE];
};
ahb_port_slave.h
#pragma once
#include <systemc.h>
#include "string.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
using namespace std;
class Ahb_Port_Master;
class Ahb_Port_Slave {
public:
tlm_utils::simple_target_socket<Ahb_Port_Slave> t_ahb_socket_;
Ahb_Port_Slave(std::string name, sc_time latency = sc_core::SC_ZERO_TIME) {
t_ahb_socket_.register_b_transport(this, &Ahb_Port_Slave::Ahb_b_transport);
}
~Ahb_Port_Slave() {
}
/* ahb slave */
virtual void Ahb_b_transport(tlm::tlm_generic_payload& trans, sc_time& delay){};
int32_t Ahb_target_bind(tlm_utils::simple_initiator_socket<Ahb_Port_Master>& socket);
private:
const sc_time LATENCY;
};
ahb_port_master.h
#pragma once
#include <systemc.h>
#include "ahb_port_slave.h"
#include "string.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
using namespace std;
class Ahb_Port_Master {
public:
tlm_utils::simple_initiator_socket<Ahb_Port_Master> i_ahb_socket;
Ahb_Port_Master(std::string name, sc_time latency = sc_core::SC_ZERO_TIME) : i_ahb_socket("i_ahb_socket"), LATENCY(latency) {
}
~Ahb_Port_Master() {
}
int32_t Ahb_Master_Send(tlm::tlm_command cmd, unsigned char* buf, sc_dt::uint64 addr, sc_dt::uint64 len);
int32_t Ahb_master_bind(tlm_utils::simple_target_socket<Ahb_Port_Slave>& socket);
private:
const sc_time LATENCY;
};
element.cpp
#include <ittypes.h>
#include <systemc>
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "tlm_utils/tlm_quantumkeeper.h"
using namespace sc_core;
using namespace std;
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#include "element.h"
element::element(sc_core::sc_module_name name, sc_clock& clock)
: sc_module(name)
, Ahb_Port_Slave("apb")
, Bus_Port_Master("bus")
, Instr_Port_Slave("instr")
, clock_(clock)
, fp16_ops_("fp16_ops")
, int_ops_("int_ops")
, fifo_left(8)
, fifo_right(8) {
SC_THREAD(ele_test_task);
sensitive << clock_.pos();
dont_initialize();
SC_THREAD(ele_left_read_task);
sensitive << clock_.pos();
dont_initialize();
SC_THREAD(ele_right_read_task);
sensitive << clock_.pos();
dont_initialize();
SC_THREAD(element_task);
sensitive << clock_.pos();
dont_initialize();
}
void element::ele_test_task() {
while (true) {
Bus_Master_Trans(tlm::tlm_command::TLM_READ_COMMAND, read, 0, 512);
wait(100, SC_NS);
}
void element::Ahb_b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) {
// tlm::tlm_command cmd = trans.get_command();
// sc_dt::uint64 addr = trans.get_address();
// unsigned char* ptr = trans.get_data_ptr();
// unsigned int len = trans.get_data_length();
// unsigned int streaming_width = trans.get_streaming_width();
// unsigned char* be = trans.get_byte_enable_ptr();
// unsigned int be_len = trans.get_byte_enable_length();
// /* 添加ahb的寄存器的读写 */
// delay += LATENCY;
// trans.set_dmi_allowed(true);
// trans.set_response_status(tlm::TLM_OK_RESPONSE);
}
相关文章:
systemC示例
main.cpp #include <memory> using namespace std; #include "top.h" int sc_main(int i, char *av[]) { // 关闭关于 IEEE 1666 标准中过时特性的警告 sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); cout <…...
C++打字模拟
改进于 文宇炽筱_潜水 c版的打字效果_c自动打字-CSDN博客https://blog.csdn.net/2401_84159494/article/details/141023898?ops_request_misc%257B%2522request%255Fid%2522%253A%25227f97863ddc9d1b2ae9526f45765b1744%2522%252C%2522scm%2522%253A%252220140713.1301023…...
国产低功耗带LCD驱动和触摸按键功能的MCU
以下是国产低功耗、集成LCD驱动和触摸按键功能的MCU精选型号及其核心特性,结合性能、功耗和适用场景进行综合推荐: 1.灵动微MM32L0130系列 257 核心特性:低功耗:待机模式功耗低至100nA,支持多种低功耗模式。 LCD驱动&a…...
在 imx93 平台调试 nau88c10 声卡
一、环境介绍 linux 版本:6.6.52 soc:imx9331 codec:nau88c10 使用的内核文件为 Image,dtb 文件为:imx93-11x11-evk.dtb 二、硬件检查 i2s 信号线要接对 i2c 控制信号建议为 4.7k 上拉 codec 供电可以按参考设计…...
机器学习-分类算法评估标准
一. 准确率 accuracy 将预测结果和测试集的目标值比较,计算预测正确的百分比 准确率越高说明模型效果越好 from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier #加载鸢尾花…...
美区TikTok解封后如何回归使用?
随着2025年初美区TikTok解封的消息引起了广泛关注,许多用户纷纷开始重新关注这一全球最受欢迎的短视频平台。在经历了数月的禁用期后,TikTok在美国市场的回归,代表了这一平台的巨大潜力和挑战。从用户的使用习惯,到平台的内容策略…...
行人识别检测数据集,yolo格式,PASICAL VOC XML,COCO JSON,darknet等格式的标注都支持,准确识别率可达99.5%
作者简介: 高科,先后在 IBM PlatformComputing从事网格计算,淘米网,网易从事游戏服务器开发,拥有丰富的C,go等语言开发经验,mysql,mongo,redis等数据库,设计模…...
grafana + Prometheus + node_exporter搭建监控大屏
本文介绍生产系统监控大屏的搭建,比较实用也是实际应用比较多的方式,希望能够帮助大家对监控系统有一定的认识。 0、规划 grafana主要是展示和报警,Prometheus用于保存监控数据,node_exporter用于实时采集各个应用服务器的事实状…...
【腾讯云】docker创建网络遇到Unable to enable SKIP DNAT rule
docker创建网络遇到Unable to enable SKIP DNAT rule 背景 今天打算在服务器上安装es,但是在创建网络时,提示 Error response from daemon: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER…...
DeepSeek R1模型解读与使用
DeepSeek在推出R1预览版两个月后,发布了R1的正式版本,并且开源了模型,开放了API调用。我们直接来解读一下这款模型。 这是官方的性能评测图。从左到右分别是DeepSeek-R1,o1正式版,32B蒸馏版R1,o1-mini&…...
AI新玩法:Flux.1图像生成结合内网穿透远程生图的解决方案
文章目录 前言1. 本地部署ComfyUI2. 下载 Flux.1 模型3. 下载CLIP模型4. 下载 VAE 模型5. 演示文生图6. 公网使用 Flux.1 大模型6.1 创建远程连接公网地址 7. 固定远程访问公网地址 前言 在这个AI技术日新月异的时代,图像生成模型已经成为了创意工作者和开发者手中…...
api开发如何确保通过非官方库解析口令的合法性?
通过非官方库解析淘宝口令可能存在违反淘宝平台规则以及法律法规的风险,很难完全确保其合法性。如果确实有需求,可从以下几个方面尽量降低风险,提高合法性: 了解法律法规 《中华人民共和国网络安全法》:需确保解析行为…...
第6章 ThreadGroup详细讲解(Java高并发编程详解:多线程与系统设计)
1.ThreadGroup 与 Thread 在Java程序中, 默认情况下, 新的线程都会被加入到main线程所在的group中, main线程的group名字同线程名。如同线程存在父子关系一样, Thread Group同样也存在父子关系。图6-1就很好地说明了父子thread、父…...
如何使用Python脚本将本地项目上传到 GitHub
前言 这里我们通过创建一个新的github仓库,来测试我们的脚本能否上传我们本地的项目,并且进行更新。首先你需要先安装 Git,关于这部分我好像没有记录过,这里我搜索看了一下,这篇博客写的Git安装详解应该是比较齐全的&…...
css动画水球图
由于echarts水球图动画会导致ios卡顿,所以纯css模拟 展示效果 组件 <template><div class"water-box"><div class"water"><div class"progress" :style"{ --newProgress: newProgress % }"><…...
Shellcode
什么是shellcode shellcode通常是软件漏洞利用过程中使用一小段机器代码 作用 1.启动shell,进行交互 2.打开服务器端口等待连接 3.反向连接端口 4.。。。 如何编写shellcode 1.设置rdi指向/bin/sh 2.rsi0,rdx0 3.rax0x3b 4.syscall进行系统调用 64位系统…...
Element使用表单重置如果不使用prop,重置无法生效
文章目录 为什么需要 prop?示例:使用 prop 的正确方式关键点总结 在 element-ui 的 el-form 组件中, prop 属性是与表单验证和表单字段绑定密切相关的,尤其在使用 resetFields() 重置表单数据时。 如果不使用 prop࿰…...
[Qt]系统相关-网络编程-TCP、UDP、HTTP协议
目录 前言 一、UDP网络编程 1.Qt项目文件 2.UDP类 QUdpSocket QNetworkDatagram 3.UDP回显服务器案例 细节 服务器设计 客户端设计 二、TCP网络编程 1.TCP类 QTcpServer QTcpSocket 2.TCP回显服务器案例 细节 服务器设计 客户端设计 三、HTTP客户端 1.HTTP…...
两台局域网电脑通过飞秋传输大文件失败的解决方案
问题描述: 局域网两台电脑之间传输大文件(超过20G),不想太复杂,就各装个飞秋。但是通过直接发送文件发现总是失败,一会就中断了。 解决方法: 主界面上有一个文件共享的按钮,通过文…...
安卓程序作为web服务端的技术实现(二):Room 实现数据存储
已经实现web服务器安卓程序作为web服务端的技术实现:AndServer 实现登录权限拦截-CSDN博客 现在需要和正常web项目类似,那么就需要操作数据库 一般web项目都是选择较为重型的数据库如MySQL,SQL server等 这里是安卓项目,我目前…...
代码工艺:实践 Spring Boot TDD 测试驱动开发
TDD 的核心理念是 “先写测试,再写功能”,其过程遵循一个严格的循环,即 Red-Green-Refactor: TDD 的流程 1. Red(编写失败的测试) 根据需求,先编写一个测试用例,描述期望的行为。…...
MySQL命令及用法(精华版)
目录 DDL(数据定义语言) 数据库操作 表操作 DML(数据操作语言) DQL(数据查询语言) 基本查询 条件查询 聚合函数 分组查询 排序查询 分页查询 DCL(数据控制语言) 用户…...
73,【5】BUUCTF WEB [网鼎杯 2020 玄武组]SSRFMe(未解出)
进入靶场 又是代码又是代码又是代码又是代码又是代码又是代码又是代码又是代码又是代码又是代码又是代码又是代码又是代码又是代码 <?php // 检查 URL 是否为内部 IP 地址 function check_inner_ip($url) {// 使用正则表达式检查 URL 格式是否以 http、https、gopher 或 d…...
修改word的作者 最后一次保存者 总编辑时间 创建时间 最后一次保存的日期
作者: 1.打开word文件 2.点击左上角的文件 3.选项 4.用户信息 5.将用户信息中的 姓名改为你需要的名字 最后一次保存者 1.word重命名为.zip文件 2.docProps中有个core.xml 3.用记事本打开有个lastModifiedBy标签,将里面内容改为你需要的名字 总编辑时…...
深入MapReduce——引入
引入 前面我们已经深入了HDFS的设计与实现,对于分布式系统也有了不错的理解。 但HDFS仅仅解决了海量数据存储和读写的问题。要想让数据产生价值,一定是需要从数据中挖掘出价值才行,这就需要我们拥有海量数据的计算处理能力。 下面我们还是…...
Formality:不可读(unread)的概念
相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482https://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 在Formality中有时会遇到不可读(unread)这个概念,本文就将对此…...
leetcode刷题记录(八十一)——236. 二叉树的最近公共祖先
(一)问题描述 236. 二叉树的最近公共祖先 - 力扣(LeetCode)236. 二叉树的最近公共祖先 - 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科 [https://baike.baidu.com/item/%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B…...
C++:将字符数组rkpryyrag,每个字母转换为其前面第13个字母后输出,如果超过a则从z再继续接着数。例如:b前面第1个字母是a。a前面第3个字母是x。
代码如下: #include <iostream> #include <string> using namespace std;int main(){string str "rkpryyrag";for (int i 0; i < str.length(); i){if (str[i] > a && str[i] < z){if (str[i] - a < 13){cout <<…...
特征选择(机器学习)
目录 1. 为什么需要特征选择2. 常见的特征选择方法2.1 过滤式(Filter Methods)小示例(用 Python 伪代码表达): 2.2 包裹式(Wrapper Methods)小示例(RFE 伪代码示例)&…...
基于微信小程序的个人健康管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
Windows系统提示RunDLL PcaWallpaperAppDetect错误修复方法
最近,Win11 24H2预览版和Win10 LTSC 2025功能更新偶尔会触发RunDLL错误弹窗 具体表现为 //英文提示 Error in C:\WINDOWS\system32\PcaSvc.dll Missing entry: PcaWallpaperAppDetect//中文提示 C:\WINDOWS\system32\PcaSvc.dll出错 丢失条目:PcaWallpaperAppDe…...
文件上传漏洞详解
第一关(JS绕过) 1.1使用bp进行绕过 先将要上传的php文件的后缀改为png,然后在上传时抓包,将png后缀再改为php,发包,此时上传成功 1.2使用js进行绕过 打开浏览器的检查,将其中的checkFile函数…...
mysql的mvcc
快速搞懂mvcc 全称 multi-version concurrency control 多版本并发控制。自动开启事务undo log读视图(read_view)结果过滤mvcc只在读已提交和可重复读隔离级别下运作读已提交隔离级别下,可重复读隔离级别下,总的来说mvcc是为了提高数据库并发性能而设计的…...
漏洞情报:为什么、要什么和怎么做
漏洞一直是网络攻防的焦点所在,因为漏洞直接或间接影响安全性的核心方面——权限。攻击者挖掘和利用漏洞,获取非授权的权限;防御方定位和消除漏洞,监测和阻断漏洞的利用,使攻击者无法利用漏洞达到其目的。漏洞信息本质…...
kotlin的协程的基础概念
Kotlin的协程是一种用于简化异步编程的强大工具。 理解协程的基础概念可以帮助开发者有效地利用其能力。 以下是Kotlin协程的一些关键基础概念: 协程(Coroutines) : 协程是一种用于处理并发任务的编程模型,它可以在单…...
C语言教程——动态内存管理(2)
文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据 总结 前言 我们之前学了动态内存管理分配函数,也是熟悉了动态内存分配函数,基于动态内存分配我把之前的通讯录做了修改,上传到了gitee上,这篇文章接着…...
LeetCode刷题 -- 45.跳跃游戏 II
题目 C代码 int jump(int* nums, int numsSize) {int i 0;int j 0;int last_i 0;int last_can 0;int max_i 0;int max_can 0;int min_jump 0;if (numsSize < 2) {//注意点1:数组小于两个的时候,只需要跳转0次;goto end;}// 注意点…...
谈谈RTMP|RTSP播放器视频view垂直|水平反转和旋转设计
技术背景 我们在做RTMP|RTSP播放器的时候,有这样的技术诉求,有的摄像头出来的数据是有角度偏差的,比如“装倒了”,或者,图像存在上下或者左右反转,这时候,就需要播放器能做响应的处理ÿ…...
vulnhub靶场【kioptrix-1靶机】
前言 靶机:kioptrix-1,IP地址为192.168.1.104 攻击:kali,IP地址为192.168.1.16 都采用虚拟机,网卡为桥接模式 文章中涉及的靶机,来源于vulnhub官网,想要下载,可自行访问官网下载&…...
PyQt5之QCalendarWidget
十八、QCalendarWidget 1.描述 提供了一个基于每月日历控件,允许用户选择一个日期。 继承自QWidget 2.功能作用 (1) 构造函数 QCalendarWidget(parent: QWidget None)(2) 日期范围 setMinimumDate(QDate date) minimumDate() -> QDate setMaximumDate(QD…...
【Qt】窗口
窗口 菜单栏 QMenuBar给菜单设置快捷键添加子菜单添加分割线设置图标 工具栏 QToolBar状态栏 QStatusBar浮动窗口 QDockWidget对话框自定义对话框通过代码方式通过图形化方式 模态对话框 Qt 内置对话框消息对话框 QMessageBox颜色对话框 QColorDialog文件对话框 QFileDialog字体…...
初阶5 排序
本章重点 排序的概念常见排序的算法思想和实现排序算法的复杂度以及稳定性分析 1.排序的概念 排序: 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。稳定性: 假定在待排序的记录序列中࿰…...
备赛蓝桥杯之第十五届职业院校组省赛第二题:分享点滴
提示:本篇文章仅仅是作者自己目前在备赛蓝桥杯中,自己学习与刷题的学习笔记,写的不好,欢迎大家批评与建议 由于个别题目代码量与题目量偏大,请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题࿰…...
qml ColumnLayout详解
1、概述 ColumnLayout 是 QML 中用于在垂直方向上排列子元素的一种布局管理器。它继承自 Item 并提供了简单的布局机制,使得子元素能够按照从上到下的顺序自动排列。ColumnLayout 通常用于创建具有垂直层次结构的用户界面。 2、重要属性 layoutDirection 类型&…...
Qt 5.14.2 学习记录 —— 십팔 对话框
文章目录 1、Qt对话框2、自定义对话框1、代码方式2、图形化方式 3、模态对话框4、QMessageBox5、QColorDialog6、QFileDialog7、QFontDialog8、QInputDialog 1、Qt对话框 Qt的对话框用QDialog类来表示,可以自定义一些类来实现自定义对话框,但需要继承自…...
AI 编程工具—Cursor进阶使用 Rules for AI
AI 编程工具—Cursor进阶使用 Rules for AI 这里配置是给所有的会话和内嵌模式的,你可以理解为是一个全局的配置 下面的代码是之前Cursor 给我们生成的,下面我们开始配置Rules ,来让Cursor生成的代码更加符合我们的编程习惯 def quick_sort(arr):"""使用快…...
SpringBoot 实现动态管理定时任务 Job的动态操作(添加、修改、启停、执行、删除)以及界面展示和具体Job的创建与执行示例
SpringBoot 实现动态管理定时任务 Job的动态操作(添加、修改、启停、执行、删除)以及界面展示和具体Job的创建与执行示例 关键接口类: CronTaskRegistrar SchedulingRunnable . 添加定时任务注册类,用来增加、删除定时任务 impo…...
FPGA中场战事
2023年10月3日,英特尔宣布由桑德拉里维拉(Sandra Rivera)担任“分拆”后独立运营的可编程事业部首席执行官。 从数据中心和人工智能(DCAI)部门总经理,转身为执掌该业务的CEO,对她取得像AMD掌门人苏姿丰博士类似的成功,无疑抱以厚望。 十年前,英特尔花费167亿美元真金白银…...
_CLASSDEF在C++中的用法详解及示例
_CLASSDEF在C++中的用法详解及示例 _CLASSDEF的定义与使用示例说明代码解析总结在C++编程中,宏(Macro)是一种预处理指令,它允许程序员在编译之前对代码进行文本替换。_CLASSDEF是一个自定义的宏,它提供了一种便捷的方式来定义类及其相关类型。本文将详细介绍_CLASSDEF在C+…...
缓存-Redis-数据结构-redis哪些数据结构是跳表实现的?
在 Redis 中,跳表(Skip List) 被用于实现 有序集合(Sorted Set) 数据结构。以下是对此实现的详细解释: Redis中的有序集合(Sorted Set) 有序集合(Sorted Set࿰…...