verilog

vim 退出所有打开文件
:qa

systemC 变量的更新

Delta Cycle 的两个主要阶段
每个 Delta Cycle 通常分为以下两个阶段:

(1) Evaluate 阶段(评估阶段)
在这个阶段,仿真内核会执行所有当前时间点上被触发(或敏感)的进程。这些进程包括:
SC_METHOD:敏感于某些事件或信号的函数。
SC_THREAD 或 SC_CTHREAD:处于可运行状态的线程进程。
这些进程会根据当前的输入信号值计算输出,但在这个阶段,信号值的更新并不会立即生效,而是被暂存起来。
Evaluate 阶段是并发的,多个进程可能同时被触发,执行顺序是不确定的(依赖于调度器实现)。
(2) Update 阶段(更新阶段)
在 Evaluate 阶段完成后,仿真内核进入 Update 阶段。
这个阶段会将 Evaluate 阶段中计算出的信号值或状态更新应用到系统中。例如,信号的赋值操作(如 sig.write(value))会在此刻真正生效。
更新完成后,可能会触发新的敏感事件(例如,某个信号的值改变后,依赖该信号的进程被唤醒)。
循环执行
如果 Update 阶段触发了新的事件,仿真内核会返回到 Evaluate 阶段,重新执行被触发的进程。
这个过程会一直重复,直到当前时间点内没有新的进程被触发为止。这种循环就构成了一个完整的 Delta Cycle。

// Learn with Examples, 2020, MIT license
#include <systemc>
using namespace sc_core;

SC_MODULE(SIGNAL) {
  sc_signal<int> s;
  SC_CTOR(SIGNAL) {
    SC_THREAD(readwrite);
  }
  void readwrite() {
    s.write(3);
    std::cout << "s = " << s << "; " << s.read() << std::endl;
    wait(SC_ZERO_TIME);
    std::cout << "after delta_cycle, s = " << s << std::endl;
    
    s = 4;
    s = 5;
    int tmp = s;
    std::cout << "s = " << tmp << std::endl;
    wait(SC_ZERO_TIME);
    std::cout << "after delta_cycle, s = " << s.read() << std::endl;
  }
};

int sc_main(int, char*[]) {
  SIGNAL signal("signal");
  signal.s = -1;
  sc_start();
  return 0;
}
s = -1; -1: read() or operator = both returns current value of signal
after delta_cycle, s = 3
s = 3
after delta_cycle, s = 5

在 SystemC 中,sc_thread 中对变量的重新赋值是否立即生效,取决于变量的类型和赋值方式。以下是详细分析:

  1. 普通变量(非 SystemC 信号)
    立即生效:普通 C++ 变量(如 int、bool、自定义类等)在 sc_thread 中的赋值会 立即生效。

但存在风险:如果多个线程或进程同时读写同一变量,可能导致 数据竞态(Data Race),因为 SystemC 的仿真内核是单线程调度,实际不存在硬件并发,但仍需注意逻辑顺序。

  1. SystemC 信号(sc_signal、sc_buffer)
    不立即生效:对 SystemC 信号(如 sc_signal)的写入(write())操作会 延迟到当前 Delta Cycle 结束时生效。

触发事件:信号值变化会在下一个 Delta Cycle 触发 value_changed_event()。

Verdi的使用## 标题
https://www.bilibili.com/video/BV1mj411M7ir/?spm_id_from=333.337.search-card.all.click&vd_source=64c6505c375a29b1e861d999e41cb60f

Shilft +L 重新加载
g

1
.trace signal
2,看波形
添加信号: 先在代码中选中信号,然后ctrl+w 或者在波形窗口菜单栏现在get signal按钮添加。
移动信号: 选中后按鼠标中键来拖动
信号完整路径: 可以在波形窗口左侧信号窗按 h键来切换显示, h可以理解为hide隐藏完整路径
保存信号: 波形窗口上方选file中的save signal,保存信号为rc文件
恢复信号:
在这里插入图片描述
光标:可以按鼠标左键和中键来显示
数clk数量: 光标框住后 点击菜单栏上的view-> signal report来直接显示
信号变色: 选中信号,按t, 可以不停变换颜色
bus 的拆分和创建: 可以看单个bit,可以将多个bit合成bus value
在这里插入图片描述

3,看source code
查找信号: 直接按? 跳出对话框,不需要按shift
跳转到函数定义: 双击
前进或后退:
在这里插入图片描述

always不代码敏感列表加粗样式****
如果always没有敏感列表怎么办?
这个话题比较有意思,你可能说怎么可能没有敏感列表?其实,还真的可以没有敏感列表,这是仿真中的用法。我们经常使用没有敏感列表的always来表示不断的触发,用此特性来生成时钟。
例如:
always #10 clk = ~clk;
其实,always块内的敏感列表就是为了控制内部语句什么时候触发的。那么可以理解为一种定时,如果没有了敏感列表,则为零延迟,那么就会不断的触发,如下:

// always block is started at time 0 units
// But when is it supposed to be repeated ?
// There is no time control, and hence it will stay and
// be repeated at 0 time units only. This continues
// in a loop and simulation will hang !
always clk = ~clk;

上面显示的示例是一个always块,它试图反转信号clk的值。该语句每0个时间单位执行一次。因此,由于语句中没有延迟,因此它将永远执行。

这是没有意义的,我们正确的做法应该给一个定时或延迟:

即使敏感度列表为空,也应该有其他形式的时间延迟。always如下所示,通过构造中的延迟语句来提前仿真时间。现在,每10个时间单位完成一次时钟反转。

always #10 clk = ~clk;
当然,这种没有敏感列表的显示延迟,是不能综合的,只能用于仿真。
————————————————

Verilog移位存放数据
代码分析
478 for (i = 0; i < (data>>1); i = i + 1) begin
479 @(posedge CA[0]);
480 #0.1 CA_in_reg[7:0] <= {CA[1],CA_in_reg[7:1]};
481 @(negedge CA[0]);
482 #0.1 CA_in_reg[7:0] <= {CA[1],CA_in_reg[7:1]};
483 end
详细解释
循环条件:

for (i = 0; i < (data>>1); i = i + 1):
data>>1表示将data右移一位,相当于data除以2并取整。
循环将执行(data>>1)次。
上升沿操作:

@(posedge CA[0]):
等待CA[0]信号的上升沿。
#0.1 CA_in_reg[7:0] <= {CA[1],CA_in_reg[7:1]}:
等待0.1个时间单位。
将CA[1]的值移到CA_in_reg[7],并将CA_in_reg[7:1]的值左移一位。
下降沿操作:

@(negedge CA[0]):
等待CA[0]信号的下降沿。
#0.1 CA_in_reg[7:0] <= {CA[1],CA_in_reg[7:1]}:
等待0.1个时间单位。
将CA[1]的值移到CA_in_reg[7],并将CA_in_reg[7:1]的值左移一位。
代码行为
这段代码的目的是通过CA[0]信号的上升沿和下降沿将CA[1]的值逐位移入CA_in_reg寄存器中。具体来说,每次CA[0]的上升沿和下降沿都会将CA[1]的值左移一位,并将CA[1]的值移到CA_in_reg[7]。

Verilog event触发机制
声明
event var;
触发
->var;
捕获
@(var);

示例:

event occur;//定义了一个可以触发的事件
always@(occur)
a <= b;

initial begin
#10
-> occur;
end

以上代码就是等待10个时间单位后,触发事件occur,之后被always块捕获,将b赋值给a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值