2021年12月14日星期二

用dff还是dffe(with functional enable)是不是做流水线时的一种选择?

遇到这种情况,以前是用sram,所以一clock肯定能读出数据,所以后面的流水线都是一拍一拍的走,遇到转移指令就stall和清流水线。

 

reg  [31:0] pc_cur    ;
wire [31:0] pc_next   ;
wire        pc_next_en;
wire [29:0] pc_seq    ;
assign bt_pc   = pc_cur;
assign pc_next = wb_cancel ? wb_target :
                 br_cancel ? br_target :
                 pr_cancel ? pr_target :
                 bt_cancel ? bt_target : {pc_seq,2'h0};
assign pc_next_en = pc_go || pr_cancel || br_cancel || wb_cancel;
assign pc_seq     = pc_cur[4:2] >= 3'h4 ? {pc_cur[31:5] + 27'h0000001,3'h0} : {pc_cur[31:5],pc_cur[4:2] + 3'h4};
assign fe_target  = fe_valid ? fe_cur[31:2] : pc_cur[31:2];
assign inst_addr  = pc_cur;
always@(posedge clock)
begin
    if(reset)
    begin
        pc_cur<=pc_init;
    end
    else
    if(pc_next_en)
    begin
        pc_cur<=pc_next;
    end
end


比如龙芯里这段代码,pc_cur是reg

其实是一个带enable的dff, dffe_s()


只有当pc_next_en为1时,pc_cur寄存器才会更新。而pc_next_en需要等pc_go或者br_branch等其中任何一种情况发生才更新pc_cur,而不是每拍pc_cur都要走。




在OpenSPARC T1里也有这样的用法,只是不是在pc path里,而是在instruction path。


   // Thread Next Instruction Register
   wire   clk_nir0;
`ifdef FPGA_SYN_CLK_EN
`else

   bw_u1_ckenbuf_6x  ckennir0(.rclk (rclk),
                              .clk  (clk_nir0),
                              .en_l (fcl_fdp_thr_s1_l[0]),
                              .tm_l (~se));
`endif
`ifdef FPGA_SYN_CLK_DFF
   dffe_s #(33) t0nir_reg(.din (icd_fdp_topdata_s1[32:0]),
                                   .q    (t0nir),
                                   .en  (~(fcl_fdp_thr_s1_l[0])), .clk(rclk), .se(se), .si(), .so());
`else

   dff_s #(33) t0nir_reg(.din  (icd_fdp_topdata_s1[32:0]),
                                   .q    (t0nir),
                                   .clk  (clk_nir0), .se(se), .si(), .so());
`endif


这里还发现个有意思的事,如果是在fpga里,就用dffe。而正式版本里是用信号控制一个clk_nir0,然后这个clk再控制dff。

2021年12月5日星期日

龙芯补充源

 

  • bjlx源

也就是大佬的补充源,有更新,已经和一年前不一样了。这里有关于这个镜像的使用方法

首先下载公钥,并导入公钥:

sudo apt-key add bjlx.key

对于Debian6,修改 /etc/apt/sources.list.d/bjlx.list 为:

deb http://www.anheng.com.cn/bjlx squeeze main
deb-src http://www.anheng.com.cn/bjlx squeeze main

最后 apt update 即可

 

 

 

http://www.anheng.com.cn/bjlx/mirrors.html

 

本目录是对debian的龙芯补充源(不限于龙芯) 包含debian5-debian11
镜像:
安恒集团:www.anheng.com.cn/bjlx
中科大:mirrors.ustc.edu.cn/bjlx
清华大学:mirrors.tuna.tsinghua.edu.cn/bjlx
南京大学:mirrors.nju.edu.cn/bjlx
腾讯软件源:mirrors.cloud.tencent.com/bjlx
北京外国语大学:mirrors.bfsu.edu.cn/bjlx
原始rsync发布: rsync://rsync.anheng.com.cn/bjlx


安装方法:
首先安装bjlx的公钥:
下载/bjlx/bjlx.key
apt-key add bjlx.key
然后建立 /etc/apt/sources.d/bjlx.list
以debian10(buster)为例:
cat /etc/apt/sources.d/bjlx.list
src http://mirrors.cloud.tencent.com/bjlx buster main
src-src http://mirrors.cloud.tencent.com/bjlx buster main
然后 apt update;apt upgrade;
文件中的buster可以修改成squeeze wheezy jessie stretch buster bullseye
分别对应到 debian6 debian7 debian8 debian9 debian10 debian11

2009-2019 liushiwei@gmail.com

 

 

 

https://www.cnblogs.com/weilinfox/p/12238559.html

 

 

 

 

http://www.anheng.com.cn/loongson/install/

2021年11月2日星期二

emacs evel-mode

 Had a problem. When I C-x C-b calling the buffer menu,  the evil-mode also get enabled.


Never happened before.


To disable it,

 

;; Enable Evil
(require 'evil)
  (evil-mode 0)

;; not use evil-mode
(evil-set-initial-state 'fundamental-mode 'emacs)
(evil-set-initial-state 'Buffer-menu-mode 'emacs)
(evil-set-initial-state 'shell-mode 'emacs)
 

 

 

Also, to check what is the current major mode, do the following query: C-h v major-mode

2021年10月1日星期五

先改gs232c_front

gs232c_front gs232c_front(
    .clock           (clk                     ),
    .reset           (~resetn                 ),
    // .br_endline      (1'b0                    ),
    .pc_init         (`GRLEN'h1c000000            ),

    .br_hint         (bru_hint_input          ),
    .br_cancel       (bru_cancel_input        ),// I, 1
    .br_target       (bru_target_input        ),// I, 32
    .br_taken        (bru_taken_input         ),// I, 1
    .br_link         (bru_link_input          ),// I, 1
    .br_jrra         (bru_jrra_input          ),// I, 1
    .br_brop         (bru_brop_input          ),// I, 1
    .br_jrop         (bru_jrop_input          ),// I, 1
    .br_sign         (bru_sign_input          ),// I, 1
    .br_pc           (bru_pc_input            ),// I, 32
    .br_link_pc      (bru_link_pc_input[`GRLEN-1:2]),// I, 32

    .wb_cancel        (wb_cancel         ),// I, 1
    .wb_target        (wb_target         ),// I, 32
    .wb_link          (wb_link           ),// I, 1
    .wb_link_pc       (wb_link_pc[`GRLEN-1:2]),// I, 32
    .wb_jrra          (wb_jrra           ),// I, 1
    .wb_jrop          (wb_jrop           ),// I, 1
    .wb_brop          (wb_brop           ),// I, 1
    .wb_pc            (wb_pc             ),// I, 32

    // .wb_endline       (1'b0              ),
    .wb_taken         (wb_taken          ),

    .inst_req         (inst_req          ),// O, 1
    .inst_addr        (inst_addr         ),// O, 32
    .inst_cancel      (inst_cancel       ),
    .inst_addr_ok     (inst_addr_ok      ),// I, 1
    .inst_valid       (inst_valid        ),// I, 8
    .inst_count       (inst_count        ),
    .inst_rdata       (inst_rdata        ),
    .inst_uncache     (inst_uncache      ),// I, 1
    .inst_ex          (inst_exception    ),// I, 1
    .inst_exccode     (inst_exccode      ),// I, 5
    .o_allow          (de2_accept         ),
    .o_valid          ({de1_port2_valid,de1_port1_valid,de1_port0_valid}),
    .o_port0_pc       (de1_port0_pc       ),// O, 32
    .o_port0_inst     (de1_port0_inst     ),// O, 32
    .o_port0_taken    (de1_port0_br_taken ),// O, 1
    .o_port0_target   (de1_port0_br_target),// O, 30
    .o_port0_ex       (de1_port0_exception),// O, 1
    .o_port0_exccode  (de1_port0_exccode  ),// O, 5
    .o_port0_hint     (de1_port0_hint     ),
    .o_port1_pc       (de1_port1_pc       ),// O, 32
    .o_port1_inst     (de1_port1_inst     ),// O, 32
    .o_port1_taken    (de1_port1_br_taken ),// O, 1
    .o_port1_target   (de1_port1_br_target),// O, 30
    .o_port1_ex       (de1_port1_exception),// O, 1
    .o_port1_exccode  (de1_port1_exccode  ),// O, 5
    .o_port1_hint     (de1_port1_hint     ),
    .o_port2_pc       (de1_port2_pc       ),// O, 32
    .o_port2_inst     (de1_port2_inst     ),// O, 32
    .o_port2_taken    (de1_port2_br_taken ),// O, 1
    .o_port2_target   (de1_port2_br_target),// O, 30
    .o_port2_ex       (de1_port2_exception),// O, 1
    .o_port2_exccode  (de1_port2_exccode  ),// O, 5

 
    `LSOC1K_CONN_BHT_RAMS
);

 

gs232c_front里面有分支预测,这个可以先不管。还有指令队列,可以先实现个简单的,每次读2条指令,用2个寄存器存这 2条指令,比如inst, inst_next。模块输出有3个端口,可以先只用port0, 通过o_valid控制。

这个模块不需要接触cache,也不需要和内存axi总线交互。L1 cache可以先不动。


先要在代码里找到inst和pc的位置。gs232c_inst_queue inst_queue里负责维护这个。而gs232c_pipe_pc是综合分支预测决定pc的位置。











之前说的inst_addr,是在lsoc1000_mainpipe cpu里输出的,用来在cache里索引。inst_addr也是gs232c_inst_queue维护的。因为每一读近来都是一个cache line,这解释了以前遇到的为啥inst_addr不是4字节的增长,而是0x10 (128bit)。读进来的是inst_rdata。























开始那么多的clock,可能是读内存的时间。


打算先搞个一次存2指令, 而port先只用一个。

一次读2指令是想跟opensparc T1学。

试着用了下

先把DUMP_TRACE设为1,生成波形。

TIME_LIMIT并不是时钟周期,而是ps。

测试代码就几句

start.S

_start:
start:
    addi.w t0, t0, 1
    addi.w t0, t0, 2
    addi.w t0, t0, 3
    addi.w t0, t0, 4
    addi.w t0, t0, 5

一开始设置成20,结果波形没什么结果,但时钟周期已经经过了几个。后来设成2000,跑了995个clock,波形终于有点变化了。

DUMP_DELAY=0
DUMP_TRACE=1
TIME_LIMIT=2000


 
 
 

 

 

比如gs232c_front里的inst_addr, cpu reset后是从0x1c000000开始执行,但后面很多个clock,inst_addr没有变化,后面0x1c000010倒是有道理,因为一次读16字节。可能是axi总线设置里随即delay?可后面地址变化也没搞明白。

 

testbench/include/testbench.h里clock_total是clock数,可以在testbench里加个选项,运行几个clock。


2021年9月27日星期一

用verilator搭的测试框架大概流程

verilator testbench 和 run_func之间的关系

 

chiplab/sims/verilator/run_func下有Makefile_run

还有configure.sh,makefile,生成的文件有output等。

 

chiplab/software/下是测试代码,还有testbench代码

u@unamed:~/prjs/chiplab/software$ ls
coremark  dhrystone  func  generic  linux  my_program  random_boot

 

func下就是func_lab3这样的测试例子。

 

verilator模拟的时候是需要先编译verilog项目,再编译testbench cpp代码,然后运行编译好的二进制代码模拟。

testbench在sims/verilator目录下,include目录里是测试框架的实现部分。

u@unamed:~/prjs/chiplab/sims/verilator/testbench$ ls
include  sim_main.cpp  simu_top.v

比如include/testbench.h里是CpuTestbench的实现。run_func/Makefile_run里的参数例如DUMP_DELAY也都是传递给testbench cpp代码的。

        ../output ${RUN_FLAG} --dump-delay $(DUMP_DELAY) --dump-trace $(DUMP_TRACE) --time-limit $(TIME_LIMIT) --save-bp-time $(SAVE_BP_TIME) --ram-save-bp-file $(RAM_SAVE_BP_FILE) --top-save-bp-file $(TOP_SAVE_BP_FILE) --restore-bp-time $(RESTORE_BP_TIME) --ram-restore-bp-file $(RAM_RESTORE_BP_FILE) --top-restore-bp-file $(TOP_RESTORE_BP_FILE)


testbench编译出来就是这个output。

u@unamed:~/prjs/chiplab/sims/verilator/run_func$ ls
config-generator.mak  config-software.mak  log   log_script  Makefile_run  obj_dir  qemu_system_run.sh
config.log            configure.sh         logs  Makefile    obj           output   tmp

比如,software/func/func_lab3下面并没有编译生成的文件,而是在下面这个目录

u@unamed:~/prjs/chiplab/sims/verilator/run_func/obj/func/func_lab3_obj/obj$ ls
data_ram.coe  data_ram.mif  inst_ram.coe  inst_ram.mif  main.bin  main.data  main.elf  rom.vlog  test.s


main.elf就是func_lab3编译生成的longarch目标代码,通过func_lab3下的convert.c转换成main.bin, main.data,最终以指令内存和数据内存的形式(data_ram.coe data_ram.mif inst_ram.coe inst_ram.mif)由testbench的ouput程序加载。


测试程序运行的流程大概是这样:

chiplab/sims/verilator/run_func下运行make

在Makefile中分别编译testbench,run_func,生成文件复制到run_func下相应的目录

(可能还有golden trace)

然后Makefile里调用Makefile_run

Makefile_run里最终调用output(也就是testbench编译生成的),把编译好的目标代码以指令内存和数据内存文件的方式送给output。

 

 

要测某一条指令,可以在run_func下写个一句汇编(比如addi.w)的程序,编译以后生成inst_ram,运行testbench后检查寄存器。

2021年8月8日星期日

can't find libnettle.so.6, ubuntu 20.04 has libnettle.so.7

 u@unamed:~/prjs$ wget  http://archive.ubuntu.com/ubuntu/pool/main/n/nettle/libnettle6_3.4-1_amd64.deb

 

u@unamed:~/prjs$ sudo dpkg -i libnettle6_3.4-1_amd64.deb

 

 libisl.so.15

http://archive.ubuntu.com/ubuntu/pool/universe/i/isl-0.18/libisl15_0.18-4_amd64.deb

 

libmpfr.so.4

http://ftp.br.debian.org/debian/pool/main/m/mpfr4/libmpfr4_3.1.5-1_amd64.deb

 

 

 

  1. To install a .deb file, simply Right click on the .deb file, and choose Kubuntu Package Menu->Install Package.

  2. Alternatively, you can also install a .deb file by opening a terminal and typing:

    sudo dpkg -i package_file.deb
  3. To uninstall a .deb file, remove it using Adept, or type:

    sudo apt-get remove package_name

 

2021年3月6日星期六

compile risc-v toolchain

git clone https://github.com/riscv/riscv-gnu-toolchain

create folder /home/uty/riscv32i

 [uty@u riscv-gnu-toolchain]$ ./configure --prefix=/home/uty/riscv32i --with-arch=rv32ia --with-abi=ilp32

[uty@u riscv-gnu-toolchain]$ make linux


I only need riscv32i, but, to successfully compile the toolchain, the minimal instruction set must be rv32ia

2021年2月16日星期二

Sipeed M1n RISC-V AI K210

 https://www.youtube.com/watch?v=GX6euKNH2iE

this video is a good start.


Here are the firmwares.

https://dl.sipeed.com/shareURL/MAIX/MaixPy/release/master/maixpy_v0.6.2_27_g4d8d4fbf0

I tried this one, maixpy_v0.6.2_27_g4d8d4fbf0_openmv_kmodel_v4_with_ide_support

To work with the MaixPy IDE, the firmware needs to have "with_ide" in it.

This one also has kmodel, so it is convenient to run face find script with this firmware.


In MAxiPy IDE, for M1n board, choose Tools->Select Board ->Sipeed Maixduino


MaixPy IDE download

https://dl.sipeed.com/MAIX/MaixPy/ide/v0.2.4


kflash_gui download

https://github.com/sipeed/kflash_gui/releases


find face script and other scripts in this github repository

https://github.com/sipeed/MaixPy_scripts/blob/master/machine_vision/face_find/demo_find_face.py



On my laptop, the board creates com4 and com5. Use com4 for IDE and kflash




K210 SoC datasheet

https://github.com/kendryte/kendryte-doc-datasheet/

pdf version

https://cdn.hackaday.io/files/1654127076987008/kendryte_datasheet_20181011163248_en.pdf


SiPeed document

https://maixpy.sipeed.com/en/




Longan Nano 是基于兆易创新(GigaDevice)最新基于 RISC-V 32 位内核的GD32VF103CBT6 单片机的极简开发板。方便广大学生、工程师、极客爱好者们接触最新一代的RISC-V处理器。了解其特性。

主芯片为 GD32VF103CBT6 ,基于芯来科技.的Bumblebee内核(指令集文档在此下载:http://dl.sipeed.com/LONGAN/Nano/DOC/.。

http://longan.sipeed.com/zh/

2021年1月24日星期日

arch linux update signature error

 try by updating the keyring first:

pacman -Sy archlinux-keyring

then try again

pacman -Syu