【SystemC】(二)第一个SystemC程序

本文以一个加法器为例,详细介绍了如何构建和运行第一个SystemC程序,包括代码文件(adder.h, adder.cpp, top.sv, Makefile, run.tcl)的作用和内容,以及在运行过程中遇到的Error-[SC-SYSCAN-OCOMP]和Error-[SC-SYSCAN-PERL-N]问题的解决方法。" 107908270,477861,Docker18中部署Nginx与Apache实战,"['Docker', '云计算', 'Linux', 'CentOS', 'Web服务器']
摘要由CSDN通过智能技术生成

目录

1  代码文件介绍

1.1  adder.h文件

1.2  adder.cpp文件

1.3  top.sv文件

1.4  Makefile文件

1.5  run.tcl文件

2  运行仿真

2.1  运行Makefile脚本

2.2  仿真结果Log

2.3  仿真结果波形

3  问题记录

3.1  Error-[SC-SYSCAN-OCOMP] Unsupported compiler

3.2  Error-[SC-SYSCAN-PERL-N] Cannot find perl5

3.3  TODO...


以一个加法器(Adder)为例,展示第一个SystemC程序。

VCS自带了一系列的SystemC例程,位于<$VCS_HOME/doc/examples/systemc/>目录下。本文所述的加法器,其完整工程文件,位于上述目录下的<./vcs/simple/>目录:

[user@centos7 simple]$ ll
-rwxrwxr-x. 1 user user    1362 Oct 29 10:23 adder.h      # Main Adder Program
-rwxrwxr-x. 1 user user    1531 Oct 29 10:23 adder.cpp    # include adder.h
-rwxrwxr-x. 1 user user    2712 Oct 30 11:09 top.v        # Testbench Top
-rwxrwxr-x. 1 user user     890 Oct 30 11:13 Makefile     # Script for Running Sim
-rwxrwxr-x. 1 user user    1305 Oct 29 10:23 README
-rw-rw-r--. 1 user user     178 Oct 30 11:06 run.tcl      # Script for Dump FSDB (Mannually Created)
...

1  代码文件介绍

1.1  adder.h文件

此文件,包含了一个SystemC形式的加法器的所有逻辑代码,包括顶层端口声明、内部逻辑实现:

SC_MODULE(adder)
{
  public:
  sc_in<sc_lv<32>>  ina;
  sc_in<sc_lv<32>>  inb;
  sc_out<sc_lv<32>> outx;

  SC_CTOR(adder): ina("ina") , inb("inb"), outx("outx") {
    SC_METHOD(adder_action);
    sensitive << ina << inb;
  }

  // As inputs are triggered, drive the output.
  void adder_action() {
    sc_lv<32> val;
    val = ina.read();
    val = val.get_word(0) + inb.read().get_word(0);
    outx.write( val );
  }
};

1.2  adder.cpp文件

此文件,仅Include了上述addr.h文件,无其他逻辑代码:

#include "adder.h"

1.3  top.sv文件

此文件,作为整个仿真的顶层,完成对加法器的实例化,以及时钟信号、加法器输入激励的构造,仿真结束的控制:

`define W 31

module top();

parameter PERIOD = 20;

reg clock;

reg [`W:0] value1;
reg [`W:0] value2;

wire [`W:0] add_wire;

integer counter;
integer direction;
integer cycle;

// SystemC model
adder add1(value1, value2, add_wire);

initial begin
  value1 = 32'b010;  // starts at 2
  value2 = 32'b000;  // starts at 0
  counter = 0;
  direction = 1;
  cycle = 0;
end

// clock generator
always begin
  clock = 1'b0;
  #PERIOD
  forever begin
   #(PERIOD/2) clock = 1'b1;
   #(PERIOD/2) clock = 1'b0;
  end
end

// stimulus generator
always @(posedge clock) begin
  value1 <= counter+2;
  value2 <= 32'b010; // stays at 2 after here.

  if (d
好的,我会尽力回答你的问题。首先,需要明确一下,SystemC是一种C++库,用于建立硬件仿真模型。 要实现一个级流水线risc-v系统模型,我们需要考虑以下几个方面: 1. 指令集:risc-v指令集是一种开源的指令集架构,我们可以在SystemC中实现这个指令集的模拟器。 2. 流水线结构:级流水线中有两个独立的流水线阶段,需要在模型中实现。 3. 寄存器:需要实现risc-v的寄存器文件,包括整数寄存器和浮点寄存器。 4. 内存:需要实现risc-v的内存模型,包括指令内存和数据内存。 基于以上考虑,我们可以开始编写级流水线risc-v系统模型。下面是一个简化的代码示例: ```c++ #include <systemc.h> SC_MODULE(RISCV) { // 模拟器需要的成员变量 int32_t pc; // 程序计数器 int32_t regfile[32]; // 寄存器文件 uint8_t memory[65536]; // 内存 // 子模块实例 SC_CTOR(RISCV) { // 初始化成员变量 pc = 0; memset(regfile, 0, sizeof(regfile)); memset(memory, 0, sizeof(memory)); // 实例化子模块 fetch = new Fetch("fetch"); decode = new Decode("decode"); execute = new Execute("execute"); memory_access = new MemoryAccess("memory_access"); write_back = new WriteBack("write_back"); // 连接信号和槽 fetch->out(pc); decode->in(pc); decode->out(ex_pc, rs1_data, rs2_data, rd); execute->in(ex_pc, rs1_data, rs2_data, rd); execute->out(mem_pc, alu_result, rd); memory_access->in(mem_pc, alu_result, rd); memory_access->out(wb_pc, mem_result, rd); write_back->in(wb_pc, mem_result, rd); } // 子模块指针 Fetch *fetch; Decode *decode; Execute *execute; MemoryAccess *memory_access; WriteBack *write_back; // 子模块 SC_MODULE(Fetch) { sc_out<int32_t> out; void run() { while (true) { out.write(pc); wait(); } } SC_CTOR(Fetch) { SC_THREAD(run); } }; SC_MODULE(Decode) { sc_in<int32_t> in; sc_out<int32_t> out_ex_pc; sc_out<int32_t> out_rs1_data; sc_out<int32_t> out_rs2_data; sc_out<int32_t> out_rd; void run() { while (true) { int32_t instruction = memory[in.read()]; int32_t opcode = instruction & 0x7F; int32_t rd = (instruction >> 7) & 0x1F; int32_t rs1 = (instruction >> 15) & 0x1F; int32_t rs2 = (instruction >> 20) & 0x1F; int32_t funct3 = (instruction >> 12) & 0x7; int32_t rs1_data = regfile[rs1]; int32_t rs2_data = regfile[rs2]; int32_t ex_pc = in.read() + 4; out_ex_pc.write(ex_pc); out_rs1_data.write(rs1_data); out_rs2_data.write(rs2_data); out_rd.write(rd); wait(); } } SC_CTOR(Decode) { SC_THREAD(run); } }; SC_MODULE(Execute) { sc_in<int32_t> in_ex_pc; sc_in<int32_t> in_rs1_data; sc_in<int32_t> in_rs2_data; sc_in<int32_t> in_rd; sc_out<int32_t> out_mem_pc; sc_out<int32_t> out_alu_result; sc_out<int32_t> out_rd; void run() { while (true) { int32_t alu_result = 0; out_mem_pc.write(in_ex_pc.read()); out_alu_result.write(alu_result); out_rd.write(in_rd.read()); wait(); } } SC_CTOR(Execute) { SC_THREAD(run); } }; SC_MODULE(MemoryAccess) { sc_in<int32_t> in_mem_pc; sc_in<int32_t> in_alu_result; sc_in<int32_t> in_rd; sc_out<int32_t> out_wb_pc; sc_out<int32_t> out_mem_result; sc_out<int32_t> out_rd; void run() { while (true) { int32_t mem_result = 0; out_wb_pc.write(in_mem_pc.read()); out_mem_result.write(mem_result); out_rd.write(in_rd.read()); wait(); } } SC_CTOR(MemoryAccess) { SC_THREAD(run); } }; SC_MODULE(WriteBack) { sc_in<int32_t> in_wb_pc; sc_in<int32_t> in_mem_result; sc_in<int32_t> in_rd; void run() { while (true) { regfile[in_rd.read()] = in_mem_result.read(); wait(); } } SC_CTOR(WriteBack) { SC_THREAD(run); } }; }; ``` 以上代码只是一个简化版,实际上还需要考虑很多细节。不过,这个模型能够帮助你了解如何使用SystemC实现一个级流水线risc-v系统模型。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值