IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> NICE的Verilog代码 -> 正文阅读

[嵌入式]NICE的Verilog代码

一、端口说明

// System	
    input                         nice_clk             ,
    input                         nice_rst_n	          ,
    output                        nice_active	       ,
    output                        nice_mem_holdup	    ,//avoid memory read or write by other devices

    // Control cmd_req
    input                         nice_req_valid       ,//E203 send a nice request
    output                        nice_req_ready       ,//nice can receive request
    input  [`E203_XLEN-1:0]       nice_req_inst        ,//custom instruction
    input  [`E203_XLEN-1:0]       nice_req_rs1         ,//the register 1
    input  [`E203_XLEN-1:0]       nice_req_rs2         ,//the register 2

    // Control cmd_rsp	
    output                        nice_rsp_valid       ,//nice send response
    input                         nice_rsp_ready       ,//e203 can receive response
    output [`E203_XLEN-1:0]       nice_rsp_rdat        ,//compute result 
    output                        nice_rsp_err    	  ,  //nice has error

    // Memory lsu_req	
    output                        nice_icb_cmd_valid   ,//nice send a memory request
    input                         nice_icb_cmd_ready   ,//e203 can receive memory request
    output [`E203_ADDR_SIZE-1:0]  nice_icb_cmd_addr    ,//memory request address
    output                        nice_icb_cmd_read    ,//0:write 1:read 
    output [`E203_XLEN-1:0]       nice_icb_cmd_wdata   ,//write data request
    output [1:0]                  nice_icb_cmd_size    ,//00:byte 01:half-word 10:word 11:reserved
    
    // Memory lsu_rsp	
    input                         nice_icb_rsp_valid   ,//e203 send memory response
    output                        nice_icb_rsp_ready   ,//nice can receive memory
    input  [`E203_XLEN-1:0]       nice_icb_rsp_rdata   ,//the data read from memory
    input                         nice_icb_rsp_err	     //error during memory access

二、RISC-V的指令

其中opcode有4个可自行扩展

?NICE使用了custom3,如下

wire opcode_custom3 = (opcode == 7'b1111011); 

三、代码中的定义

1、指令相关

定义opcode为指令的{6->0},rv32_func3为{14->12}, rv32_func7为{31->25}

wire [6:0] opcode      = {7{nice_req_valid}} & nice_req_inst[6:0];  //nice_req_valid=1, op == construcion[6:0]
wire [2:0] rv32_func3  = {3{nice_req_valid}} & nice_req_inst[14:12];//nice_req_valid=1, func3 == construcion[14:12]
wire [6:0] rv32_func7  = {7{nice_req_valid}} & nice_req_inst[31:25];//nice_req_valid=1, func7 == construcion[31:25]

定义扩展模式custom3 = 7'h3b

wire opcode_custom3 = (opcode == 7'b1111011);

定义func3和func7相关

   wire rv32_func3_000 = (rv32_func3 == 3'b000); 
   wire rv32_func3_001 = (rv32_func3 == 3'b001); 
   wire rv32_func3_010 = (rv32_func3 == 3'b010); 
   wire rv32_func3_011 = (rv32_func3 == 3'b011); 
   wire rv32_func3_100 = (rv32_func3 == 3'b100); 
   wire rv32_func3_101 = (rv32_func3 == 3'b101); 
   wire rv32_func3_110 = (rv32_func3 == 3'b110); 
   wire rv32_func3_111 = (rv32_func3 == 3'b111); 

   wire rv32_func7_0000000 = (rv32_func7 == 7'b0000000); 
   wire rv32_func7_0000001 = (rv32_func7 == 7'b0000001); 
   wire rv32_func7_0000010 = (rv32_func7 == 7'b0000010); 
   wire rv32_func7_0000011 = (rv32_func7 == 7'b0000011); 
   wire rv32_func7_0000100 = (rv32_func7 == 7'b0000100); 
   wire rv32_func7_0000101 = (rv32_func7 == 7'b0000101); 
   wire rv32_func7_0000110 = (rv32_func7 == 7'b0000110); 
   wire rv32_func7_0000111 = (rv32_func7 == 7'b0000111); 

定义三条自定义指令在custom3情况下与func3、func7的关系

wire custom3_lbuf     = opcode_custom3 & rv32_func3_010 & rv32_func7_0000001;//the instrution is {7'h01,10'hxx,3'h2,5'hxx,7'h3b}
wire custom3_sbuf     = opcode_custom3 & rv32_func3_010 & rv32_func7_0000010;//the instrution is {7'h02,10'hxx,3'h2,5'hxx,7'h3b}
wire custom3_rowsum   = opcode_custom3 & rv32_func3_110 & rv32_func7_0000110;//the instrution is {7'h06,10'hxx,3'h2,5'hxx,7'h3b}

具体的来说,三条指令如下?

指令func3?func732位的指令读取写回
custom3_lbuf3'h27'h01{7'h01,10'hxx,3'h2,5'hxx,7'h7b}rs1
custom3_sbuf3'h27'h02{7'h02,10'hxx,3'h2,5'hxx,7'h7b}rs1
custom3_rowsum3'h67'h06{7'h06,10'hxx,3'h6,5'hxx,7'h7b}rs1rd


定义两个信号,分别代表协处理器指令和需要访问memory

  
   //  multi-cyc op 
   
   wire custom_multi_cyc_op = custom3_lbuf | custom3_sbuf | custom3_rowsum;//the instrution is made by nice
   // need access memory
   wire custom_mem_op = custom3_lbuf | custom3_sbuf | custom3_rowsum;//the instrution is made by nice and need memory 
 

2、状态机相关

状态机的4状态,空闲和三个指令

   parameter NICE_FSM_WIDTH = 2; 
   parameter IDLE     = 2'd0; 
   parameter LBUF     = 2'd1; 
   parameter SBUF     = 2'd2; 
   parameter ROWSUM   = 2'd3; 

定义现态和次态,以及四个状态的下个状态

   wire [NICE_FSM_WIDTH-1:0] state_r; 
   wire [NICE_FSM_WIDTH-1:0] nxt_state; 
   wire [NICE_FSM_WIDTH-1:0] state_idle_nxt; 
   wire [NICE_FSM_WIDTH-1:0] state_lbuf_nxt; 
   wire [NICE_FSM_WIDTH-1:0] state_sbuf_nxt; 
   wire [NICE_FSM_WIDTH-1:0] state_rowsum_nxt; 

定义现在是什么状态的四个信号

   wire state_is_idle     = (state_r == IDLE); 
   wire state_is_lbuf     = (state_r == LBUF); 
   wire state_is_sbuf     = (state_r == SBUF); 
   wire state_is_rowsum   = (state_r == ROWSUM); 

定义状态离开使能信号,四个状态的和真实状态的,共5个

   wire state_idle_exit_ena; 
   wire state_lbuf_exit_ena; 
   wire state_sbuf_exit_ena; 
   wire state_rowsum_exit_ena; 
   wire state_ena;

不知道干什么用的,illgel_instr为0代表是协处理器指令,为1代表不是

   wire nice_req_hsked;
   wire nice_rsp_hsked;
   wire nice_icb_rsp_hsked;
   wire illgel_instr = ~(custom_multi_cyc_op);

   wire lbuf_icb_rsp_hsked_last;
   wire sbuf_icb_rsp_hsked_last;
   wire rowsum_done;

四、功能

1、状态转换

①IDLE的次态选择

当指令为协处理器扩展的三条指令,则state_idle_nxt为相应的指令对应的状态,否则保持IDLE不变

   assign state_idle_nxt =  custom3_lbuf    ? LBUF   : 
                            custom3_sbuf    ? SBUF   :
                            custom3_rowsum  ? ROWSUM :
			    IDLE;

三个指令状态的次态,都为IDLE

assign state_lbuf_nxt = IDLE;
assign state_sbuf_nxt = IDLE;
assign state_rowsum_nxt = IDLE;

给状态离开使能信号赋值

当现态为IDLE,并且(nice_req_hsked),并且当前为三指令之一,state_idle_exit_ena为高

assign state_idle_exit_ena = state_is_idle & nice_req_hsked & ~illgel_instr; 

现态为lbuf,并且(lbuf_icb_rsp_hsked_last),state_lbuf_exit_ena为高

assign state_lbuf_exit_ena = state_is_lbuf & lbuf_icb_rsp_hsked_last;

现态为sbuf,并且(sbuf_icb_rsp_hsked_last),state_sbuf_exit_ena为高

assign state_sbuf_exit_ena = state_is_sbuf & sbuf_icb_rsp_hsked_last;

现态为rowsum,并且rowsum_done为高,state_rowsum_exit_ena为高

assign state_rowsum_exit_ena = state_is_rowsum & rowsum_done;

④次态赋值

当前状态的离开使能为高时,为其对应的次态,否则为2'b00即IDLE

   assign nxt_state =   ({NICE_FSM_WIDTH{state_idle_exit_ena   }} & state_idle_nxt   )
                      | ({NICE_FSM_WIDTH{state_lbuf_exit_ena   }} & state_lbuf_nxt   ) 
                      | ({NICE_FSM_WIDTH{state_sbuf_exit_ena   }} & state_sbuf_nxt   ) 
                      | ({NICE_FSM_WIDTH{state_rowsum_exit_ena }} & state_rowsum_nxt ) 
                      ;

状态转换使能,为四个使能的或

   assign state_ena =   state_idle_exit_ena | state_lbuf_exit_ena 
                      | state_sbuf_exit_ena | state_rowsum_exit_ena;

⑥时序状态机

调用sirv_gnrl_dfflr,D触发器,实现状态机

sirv_gnrl_dfflr #(NICE_FSM_WIDTH)   state_dfflr 
    (state_ena, nxt_state, state_r, nice_clk, nice_rst_n);

2、一个lbuf的计数器

①信号定义

lbuf_cnt_r????????????????现在计数值
lbuf_cnt_nxt????????下一个计数值
lbuf_cnt_clr????????计数清零,使能
lbuf_cnt_incr????????????????计数增加,使能
lbuf_cnt_ena计数,D触发器,使能
lbuf_cnt_last????????计数到最后值
lbuf_icb_rsp_hsked状态机为lbuf,并且储存响应握手成功
nice_rsp_valid_lbuf状态机为lbuf,计数到最后值,E203发出储存响应信号
nice_icb_cmd_valid_lbuf状态机为lbuf,计数值小于最后值

②信号赋值

1)已知assign nice_icb_rsp_hsked = nice_icb_rsp_valid & nice_icb_rsp_ready;并且nice_icb_rsp_ready is 1'b1 always,所以nice_icb_rsp_hsked = nice_icb_rsp_valid

所以lbuf_icb_rsp_hsked,当前状态为lbuf,储存响应握手

2)lbuf_icb_rsp_hsked_last,当前状态为lbuf,储存响应握手,计数为最后值

3)lbuf_cnt_last即计数到最后值,也就是lbuf_cnt_r为clonum2‘b10

4)已知assign nice_req_hsked = nice_req_valid & nice_req_ready;

所以lbuf_cnt_clr含义为当前指令为lbuf,命令请求握手

5)lbuf_cnt_incr为当前状态为lbuf,储存响应握手,计数值不是最后值

6)lbuf_cnt_ena,当前指令为lbuf,命令请求握手;或者当前状态lbuf,储存指令握手,计数值不是最后值

7)当前指令lbuf,命令请求握手,lbuf_cnt_nxt归零;当前状态lbuf,储存响应握手,计数值不是最后值,lbuf_cnt_nxt为lbuf_cnt_r+1

8)nice_rsp_valid_lbuf,当前状态为lbuf,计数值为最后值,E203发出储存响应信号

9)nice_icb_cmd_valid_lbuf,当前状态为lbuf,且现计数值小于最后值

   assign lbuf_icb_rsp_hsked = state_is_lbuf & nice_icb_rsp_hsked;
   assign lbuf_icb_rsp_hsked_last = lbuf_icb_rsp_hsked & lbuf_cnt_last;
   assign lbuf_cnt_last = (lbuf_cnt_r == clonum);
   assign lbuf_cnt_clr = custom3_lbuf & nice_req_hsked;
   assign lbuf_cnt_incr = lbuf_icb_rsp_hsked & ~lbuf_cnt_last;
   assign lbuf_cnt_ena = lbuf_cnt_clr | lbuf_cnt_incr;
   assign lbuf_cnt_nxt =   ({ROWBUF_IDX_W{lbuf_cnt_clr }} & {ROWBUF_IDX_W{1'b0}})
                         | ({ROWBUF_IDX_W{lbuf_cnt_incr}} & (lbuf_cnt_r + 1'b1) )
                         ;
   // nice_rsp_valid wait for nice_icb_rsp_valid in LBUF
   assign nice_rsp_valid_lbuf = state_is_lbuf & lbuf_cnt_last & nice_icb_rsp_valid;

   // nice_icb_cmd_valid sets when lbuf_cnt_r is not full in LBUF
   assign nice_icb_cmd_valid_lbuf = (state_is_lbuf & (lbuf_cnt_r < clonum));

③D触发器构成时序计数器

时钟:nice_clk ; 复位信号:nice_rst_n ; 使能信号:lbuf_cnt_ena ;

输入数据lbuf_cnt_nxt ; 输出数据:lbuf_cnt_r

  sirv_gnrl_dfflr #(ROWBUF_IDX_W)   lbuf_cnt_dfflr 
    (lbuf_cnt_ena, lbuf_cnt_nxt, lbuf_cnt_r, nice_clk, nice_rst_n);

3、sbuf计数器

①信号定义

sbuf_cnt_r当前计数值
subf_cnt_nxt下个计数值
sbuf_cnt_clrsbuf_icb_rsp_hsked_last
sbuf_cnt_incrsbuf_cnt增加,使能
sbuf_cnt_enaD触发器,使能
sbuf_cnt_last当前计数值为最后值
sbuf_icb_cmd_hsked当前状态为sbuf,或(状态为IDLE且指令为sbuf),储存握手成功
sbuf_icb_rsp_hsked当前状态为sbuf,储存响应握手成功
nice_rsp_valid_sbuf状态机为sbuf,计数到最后值,E203发出储存响应信号
nice_icb_cmd_valid_sbuf状态为sbuf,sbuf_cmd_cnt_r小于等于最后值,sbuf_cnt不是最后值
nice_icb_cmd_hsked储存请求握手成功

②信号赋值

1)sbuf_icb_cmd_hsked,当前状态为sbuf,或(idle状态指令为sbuf),储存请求握手成功

2)sbuf_icb_rsp_hsked,当前状态sbuf,储存响应握手

3)sbuf_icb_rsp_hsked_last,当前状态sbuf,储存响应握手,计数值为最后值

4)sbuf_cnt_last,计数值为最后值

5)sbuf_cnt_clr,就是sbuf_icb_rsp_hsked_last,当前状态sbuf,储存响应握手,计数值为最后值

6)sbuf_cnt_incr,当前状态sbuf,储存响应握手,计数值不是最后值

7)sbuf_cnt_ena,当前状态sbuf,储存响应握手

8)sbuf_cnt_nxt,当前状态sbuf,储存响应握手,(计数值为最后值则为2'b00;否则为现在计数值+1)

9)nice_rsp_valid_sbuf,当前状态sbuf,计数值为最后值,E203发出储存响应信号

   assign sbuf_icb_cmd_hsked = (state_is_sbuf | (state_is_idle & custom3_sbuf)) & nice_icb_cmd_hsked;
   assign sbuf_icb_rsp_hsked = state_is_sbuf & nice_icb_rsp_hsked;
   assign sbuf_icb_rsp_hsked_last = sbuf_icb_rsp_hsked & sbuf_cnt_last;
   assign sbuf_cnt_last = (sbuf_cnt_r == clonum);
   //assign sbuf_cnt_clr = custom3_sbuf & nice_req_hsked;
   assign sbuf_cnt_clr = sbuf_icb_rsp_hsked_last;
   assign sbuf_cnt_incr = sbuf_icb_rsp_hsked & ~sbuf_cnt_last;
   assign sbuf_cnt_ena = sbuf_cnt_clr | sbuf_cnt_incr;
   assign sbuf_cnt_nxt =   ({ROWBUF_IDX_W{sbuf_cnt_clr }} & {ROWBUF_IDX_W{1'b0}})
                         | ({ROWBUF_IDX_W{sbuf_cnt_incr}} & (sbuf_cnt_r + 1'b1) )
                         ;
   // nice_rsp_valid wait for nice_icb_rsp_valid in SBUF
   assign nice_rsp_valid_sbuf = state_is_sbuf & sbuf_cnt_last & nice_icb_rsp_valid;

③D触发器构成时序计数器

  sirv_gnrl_dfflr #(ROWBUF_IDX_W)   sbuf_cnt_dfflr 
    (sbuf_cnt_ena, sbuf_cnt_nxt, sbuf_cnt_r, nice_clk, nice_rst_n);

4、sbuf_cmd计数器

①信号定义

sbuf_cmd_cnt_rsbuf_cmd现计数值
sbuf_cmd_cnt_nxtsbuf_cmd下个计数值
sbuf_cmd_cnt_clr当前状态sbuf,储存响应握手,sbuf计数值为最后值
sbuf_cmd_cnt_incr当前状态为sbuf,或(idle状态指令为sbuf),储存请求握手成功,subf_cmd计数值不是最后值
sbuf_cmd_cnt_ena(当前状态sbuf,储存响应握手,sbuf计数值为最后值)或(当前状态为sbuf,或(idle状态指令为sbuf),储存请求握手成功,subf_cmd计数值不是最后值)
sbuf_cmd_cnt_lastsbuf_cmd计数值为最后值

②信号赋值

1)sbuf_cmd_cnt_last,sbuf_cmd计数值为最后值

2)sbuf_cmd_cnt_clr,当前状态sbuf,储存响应握手,sbuf计数值为最后值

3)sbuf_cmd_cnt_incr,当前状态为sbuf,或(idle状态指令为sbuf),储存请求握手成功,subf_cmd计数值不是最后值

4)sbuf_cmd_cnt_ena,(当前状态sbuf,储存响应握手,sbuf计数值为最后值)或(当前状态为sbuf,或(idle状态指令为sbuf),储存请求握手成功,subf_cmd计数值不是最后值)

5)sbuf_cmd_cnt_nxt,当前状态sbuf,储存响应握手,sbuf计数为最后值,为2'b00;当前状态为sbuf,或(idle状态指令为sbuf),储存请求握手成功,sbuf_cmd计数值不是最后值,为sbuf_cmd_cnt_r+1

6)nice_icb_cmd_valid_sbuf,当前状态sbuf,sbuf_cmd小于等于最后值,sbuf不等于最后值

   assign sbuf_cmd_cnt_last = (sbuf_cmd_cnt_r == clonum);
   assign sbuf_cmd_cnt_clr = sbuf_icb_rsp_hsked_last;
   assign sbuf_cmd_cnt_incr = sbuf_icb_cmd_hsked & ~sbuf_cmd_cnt_last;
   assign sbuf_cmd_cnt_ena = sbuf_cmd_cnt_clr | sbuf_cmd_cnt_incr;
   assign sbuf_cmd_cnt_nxt =   ({ROWBUF_IDX_W{sbuf_cmd_cnt_clr }} & {ROWBUF_IDX_W{1'b0}})
                             | ({ROWBUF_IDX_W{sbuf_cmd_cnt_incr}} & (sbuf_cmd_cnt_r + 1'b1) )
                             ;
   // nice_icb_cmd_valid sets when sbuf_cmd_cnt_r is not full in SBUF
   assign nice_icb_cmd_valid_sbuf = (state_is_sbuf & (sbuf_cmd_cnt_r <= clonum) & (sbuf_cnt_r != clonum));

③D触发器构成时序计数器

   sirv_gnrl_dfflr #(ROWBUF_IDX_W)   sbuf_cmd_cnt_dfflr 
    (sbuf_cmd_cnt_ena, sbuf_cmd_cnt_nxt, sbuf_cmd_cnt_r, nice_clk, nice_rst_n);

5、rowsum的rowbuf counter

①信号定义

   wire [ROWBUF_IDX_W-1:0] rowbuf_cnt_r; 
   wire [ROWBUF_IDX_W-1:0] rowbuf_cnt_nxt; 
   wire rowbuf_cnt_clr;
   wire rowbuf_cnt_incr;
   wire rowbuf_cnt_ena;
   wire rowbuf_cnt_last;
   wire rowbuf_icb_rsp_hsked;
   wire rowbuf_rsp_hsked;
   wire nice_rsp_valid_rowsum;

②信号赋值

   assign rowbuf_rsp_hsked = nice_rsp_valid_rowsum & nice_rsp_ready;
   assign rowbuf_icb_rsp_hsked = state_is_rowsum & nice_icb_rsp_hsked;
   assign rowbuf_cnt_last = (rowbuf_cnt_r == clonum);
   assign rowbuf_cnt_clr = rowbuf_icb_rsp_hsked & rowbuf_cnt_last;
   assign rowbuf_cnt_incr = rowbuf_icb_rsp_hsked & ~rowbuf_cnt_last;
   assign rowbuf_cnt_ena = rowbuf_cnt_clr | rowbuf_cnt_incr;
   assign rowbuf_cnt_nxt =   ({ROWBUF_IDX_W{rowbuf_cnt_clr }} & {ROWBUF_IDX_W{1'b0}})
                           | ({ROWBUF_IDX_W{rowbuf_cnt_incr}} & (rowbuf_cnt_r + 1'b1))
                           ;

③D触发器构成时序计数器

  sirv_gnrl_dfflr #(ROWBUF_IDX_W)   rowbuf_cnt_dfflr 
    (rowbuf_cnt_ena, rowbuf_cnt_nxt, rowbuf_cnt_r, nice_clk, nice_rst_n);

6、rowsum的recieve data buffer

①信号定义

   wire rcv_data_buf_ena;
   wire rcv_data_buf_set;
   wire rcv_data_buf_clr;
   wire rcv_data_buf_valid;
   wire [`E203_XLEN-1:0] rcv_data_buf; 
   wire [ROWBUF_IDX_W-1:0] rcv_data_buf_idx; 
   wire [ROWBUF_IDX_W-1:0] rcv_data_buf_idx_nxt; 

②信号赋值

   assign rcv_data_buf_set = rowbuf_icb_rsp_hsked;
   assign rcv_data_buf_clr = rowbuf_rsp_hsked;
   assign rcv_data_buf_ena = rcv_data_buf_clr | rcv_data_buf_set;
   assign rcv_data_buf_idx_nxt =   ({ROWBUF_IDX_W{rcv_data_buf_clr}} & {ROWBUF_IDX_W{1'b0}})
                                 | ({ROWBUF_IDX_W{rcv_data_buf_set}} & rowbuf_cnt_r        );

③D触发器构成时序计数器

第一个是使能信号的一个时钟延迟

第二个是输入数据的缓冲

第三个是对rowbuf写入的序号

  sirv_gnrl_dfflr #(1)   rcv_data_buf_valid_dfflr 
    (1'b1, rcv_data_buf_ena, rcv_data_buf_valid, nice_clk, nice_rst_n);
  sirv_gnrl_dfflr #(`E203_XLEN)   rcv_data_buf_dfflr 
    (rcv_data_buf_ena, nice_icb_rsp_rdata, rcv_data_buf, nice_clk, nice_rst_n);
  sirv_gnrl_dfflr #(ROWBUF_IDX_W)   rowbuf_cnt_d_dfflr 
    (rcv_data_buf_ena, rcv_data_buf_idx_nxt, rcv_data_buf_idx, nice_clk, nice_rst_n);

7、rowsum的累加

①信号定义

   wire [`E203_XLEN-1:0] rowsum_acc_r;
   wire [`E203_XLEN-1:0] rowsum_acc_nxt;
   wire [`E203_XLEN-1:0] rowsum_acc_adder;
   wire rowsum_acc_ena;
   wire rowsum_acc_set;
   wire rowsum_acc_flg;
   wire nice_icb_cmd_valid_rowsum;
   wire [`E203_XLEN-1:0] rowsum_res;

②信号赋值

2)rowsum_acc_flg,rcv_data_buf_idx非零,且上个周期的状态为rowsum时(储存响应握手或E203发出nice_rsp_ready信号)

   assign rowsum_acc_set = rcv_data_buf_valid & (rcv_data_buf_idx == {ROWBUF_IDX_W{1'b0}});
   assign rowsum_acc_flg = rcv_data_buf_valid & (rcv_data_buf_idx != {ROWBUF_IDX_W{1'b0}});
   assign rowsum_acc_adder = rcv_data_buf + rowsum_acc_r;
   assign rowsum_acc_ena = rowsum_acc_set | rowsum_acc_flg;
   assign rowsum_acc_nxt =   ({`E203_XLEN{rowsum_acc_set}} & rcv_data_buf)
                           | ({`E203_XLEN{rowsum_acc_flg}} & rowsum_acc_adder)
                           ;
   assign rowsum_done = state_is_rowsum & nice_rsp_hsked;
   assign rowsum_res  = rowsum_acc_r;

   // rowsum finishes when the last acc data is added to rowsum_acc_r  
   assign nice_rsp_valid_rowsum = state_is_rowsum & (rcv_data_buf_idx == clonum) & ~rowsum_acc_flg;

   // nice_icb_cmd_valid sets when rcv_data_buf_idx is not full in LBUF
   assign nice_icb_cmd_valid_rowsum = state_is_rowsum & (rcv_data_buf_idx < clonum) & ~rowsum_acc_flg;

③D触发器构成时序

累加的时序操作

   sirv_gnrl_dfflr #(`E203_XLEN)   rowsum_acc_dfflr 
    (rowsum_acc_ena, rowsum_acc_nxt, rowsum_acc_r, nice_clk, nice_rst_n);

8、rowbuf

rowbuf是数据缓存,lbuf和rowsum会写入,sbuf会读出

①信号定义

rowbuf_r4个32位的数据
rowbuf_wdata4个32位的数据
rowbuf_we4位宽的数据
rowbuf_idx_muxrowbuf的序号选择
rowbuf_wdata_muxrowbuf的写入数据选择
rowbuf_wr_muxrowbuf的写入信号选择
lbuf_dixlbuf写入的序号
lbuf_wrlbuf写入的使能
lbuf_wdatalbuf写入的数据
rowsum_idxrowsum写入的序号
rcv_data_buf_validrowsum写入的使能
rowsum_wdatarowsum写入的数据

②信号赋值

写入的选择

1)lbuf_idx,写入序号选择,为lbuf_cnt_r,即lbuf计数的时序输出,当前的计数值,从0到2

2)lbuf_wr,写入使能,为lbuf_icb_rsp_hsked,即当前状态为lbuf,储存响应握手

3)lbuf_wdata,写入数据,外部输入的从memory读取的数据

4)rowsum_dix,写入序号选择,为rcv_data_buf_idx,当前的计数值,从0到2

5)rowsum_wr,写入使能,为rcv_data_buf-valid,是rcv_data_buf_ena缓冲一个时钟

6)rowsum_wdata,写入数据,为rowbuf_r当前数据与rcv_data_buf的加和

7)rowbuf_idx_mux,写入序号选择,若lbuf_wr为高,则为luf_idx,若rowsum_wr为高,则为rowsum_dix

8)rowbuf_wr_mux,写入使能选择,lbuf_wr与rowsum_wr的或

9)rowbuf_wdat_mux,写入数据选择

// lbuf write to rowbuf
   wire [ROWBUF_IDX_W-1:0] lbuf_idx = lbuf_cnt_r; 
   wire lbuf_wr = lbuf_icb_rsp_hsked; 
   wire [`E203_XLEN-1:0] lbuf_wdata = nice_icb_rsp_rdata;

// rowsum write to rowbuf(column accumulated data)
   wire [ROWBUF_IDX_W-1:0] rowsum_idx = rcv_data_buf_idx; 
   wire rowsum_wr = rcv_data_buf_valid; 
   wire [`E203_XLEN-1:0] rowsum_wdata = rowbuf_r[rowsum_idx] + rcv_data_buf;   

// rowbuf write mux
   assign rowbuf_wdat_mux =   ({`E203_XLEN{lbuf_wr  }} & lbuf_wdata  )
                            | ({`E203_XLEN{rowsum_wr}} & rowsum_wdata)
                            ;
   assign rowbuf_wr_mux   =  lbuf_wr | rowsum_wr;
   assign rowbuf_idx_mux  =   ({ROWBUF_IDX_W{lbuf_wr  }} & lbuf_idx  )
                            | ({ROWBUF_IDX_W{rowsum_wr}} & rowsum_idx)
                            ;  

③D触发器构成时序

实例化4个32位的D触发器

1)rowbuf_we为使能信号,为rowbuf_wr_mux与一个表达式的与,i的低2位与rowbuf_idx_mux相等才可以

2)rowbuf_wdat为输入数据,使能时为rowbuf_wdat_mux

   // rowbuf inst
   genvar i;
   generate 
     for (i=0; i<ROWBUF_DP; i=i+1) begin:gen_rowbuf
       assign rowbuf_we[i] =   (rowbuf_wr_mux & (rowbuf_idx_mux == i[ROWBUF_IDX_W-1:0]))
                             ;
  
       assign rowbuf_wdat[i] =   ({`E203_XLEN{rowbuf_we[i]}} & rowbuf_wdat_mux   )
                               ;
  
       sirv_gnrl_dfflr #(`E203_XLEN) rowbuf_dfflr (rowbuf_we[i], rowbuf_wdat[i], rowbuf_r[i], nice_clk, nice_rst_n);
     end
   endgenerate

9、memory的地址

①信号说明

nice_icb_cmd_hsked储存请求握手
lbuf_maddr_enalbuf,访问memory的使能
sbuf_maddr_enasbuf,访问memory的使能
rowsum_maddr_enarowsum,访问memory的使能
maddr_ena访问memory的使能
maddr_ena_dile访问memory的使能,且当前状态为idle
maddr_acc_op1操作数1
maddr_acc_op2操作数2
maddr_acc_ena访问memory的使能


1)nice_icb_cmd_hsked,储存请求握手②信号赋值

2)lbuf_maddr_ena,(当前状态为idle,命令为lbuf,并且储存请求握手)或(当前状态lbuf,储存请求握手)

3)sbuf_maddr_ena,(当前状态为idle,命令为sbuf,并且储存请求握手)或(当前状态sbuf,储存请求握手)

4)rowsum_maddr_ena,(当前状态为idle,命令为rowsum,并且储存请求握手)或(当前状态rowsum,储存请求握手)

5)maddr_ena,(当前状态为idle,命令有效,并且储存请求握手)或(当前状态非idle,储存请求握手)

6)maddr_ena_idle,当前状态为idle,命令为有效,并且储存请求握手

7)maddr_acc_op1,当前状态为idle,命令为有效,并且储存请求握手,为寄存器1值,否则为maddr_acc_r

8)maddr_acc_op2,32/8 = 4,所以每次要加4

9)maddr_acc_next,下一个地址,为当前地址+4

10)maddr_acc_ena,为(当前状态为idle,命令有效,并且储存请求握手)或(当前状态非idle,储存请求握手)

assign nice_icb_cmd_hsked = nice_icb_cmd_valid & nice_icb_cmd_ready; 
   // custom3_lbuf 
   //wire [`E203_XLEN-1:0] lbuf_maddr    = state_is_idle ? nice_req_rs1 : maddr_acc_r ; 
   wire lbuf_maddr_ena    =   (state_is_idle & custom3_lbuf & nice_icb_cmd_hsked)
                            | (state_is_lbuf & nice_icb_cmd_hsked)
                            ;

   // custom3_sbuf 
   //wire [`E203_XLEN-1:0] sbuf_maddr    = state_is_idle ? nice_req_rs1 : maddr_acc_r ; 
   wire sbuf_maddr_ena    =   (state_is_idle & custom3_sbuf & nice_icb_cmd_hsked)
                            | (state_is_sbuf & nice_icb_cmd_hsked)
                            ;

   // custom3_rowsum
   //wire [`E203_XLEN-1:0] rowsum_maddr  = state_is_idle ? nice_req_rs1 : maddr_acc_r ; 
   wire rowsum_maddr_ena  =   (state_is_idle & custom3_rowsum & nice_icb_cmd_hsked)
                            | (state_is_rowsum & nice_icb_cmd_hsked)
                            ;

   // maddr acc 
   //wire  maddr_incr = lbuf_maddr_ena | sbuf_maddr_ena | rowsum_maddr_ena | rbuf_maddr_ena;
   wire  maddr_ena = lbuf_maddr_ena | sbuf_maddr_ena | rowsum_maddr_ena;
   wire  maddr_ena_idle = maddr_ena & state_is_idle;

   wire [`E203_XLEN-1:0] maddr_acc_op1 = maddr_ena_idle ? nice_req_rs1 : maddr_acc_r; // not reused
   wire [`E203_XLEN-1:0] maddr_acc_op2 = maddr_ena_idle ? `E203_XLEN'h4 : `E203_XLEN'h4; 

   wire [`E203_XLEN-1:0] maddr_acc_next = maddr_acc_op1 + maddr_acc_op2;
   wire  maddr_acc_ena = maddr_ena;

③ D触发器

使能信号:maddr_acc_ena,输入数据:maddr_acc_next,输出:maddr_acc_r

sirv_gnrl_dfflr #(`E203_XLEN)   maddr_acc_dfflr 
    (maddr_acc_ena, maddr_acc_next, maddr_acc_r, nice_clk, nice_rst_n);

10、请求响应的信号

1)nice_req_hsked,命令请求握手

2)nice_req_ready,nice发出的命令请求握手信号,当前状态是idle,且指令有效,则为nice_icb_cmd_ready,否则为1'b1

3)nice_rsp_hsked,命令响应握手

4)nice_icb_rsp_hsked,储存响应握手

5)nice_rsp_valid,(当前状态lbuf,lbuf计数值为最后值,E203发出储存响应信号)或(当前状态sbuf,sbuf计数值为最后值,E203发出储存响应信号)或(当前状态rowsum,rcv_data_buf_idx计数值为最后值,rowsum_acc_flg为低)或(rcv_data_buf_idx非零,且上个周期的状态为rowsum时(储存响应握手或E203发出nice_rsp_ready信号))

6)nice_rsp_rdat,当前状态为rowsum时为rowsum_res

7)nice_rsp_err,储存响应握手且在访问memory时出错


   // Control cmd_req
   
   assign nice_req_hsked = nice_req_valid & nice_req_ready;
   assign nice_req_ready = state_is_idle & (custom_mem_op ? nice_icb_cmd_ready : 1'b1);

   
   // Control cmd_rsp
   
   assign nice_rsp_hsked = nice_rsp_valid & nice_rsp_ready; 
   assign nice_icb_rsp_hsked = nice_icb_rsp_valid & nice_icb_rsp_ready;
   assign nice_rsp_valid = nice_rsp_valid_rowsum | nice_rsp_valid_sbuf | nice_rsp_valid_lbuf;
   assign nice_rsp_rdat  = {`E203_XLEN{state_is_rowsum}} & rowsum_res;

   // memory access bus error
   //assign nice_rsp_err_irq  =   (nice_icb_rsp_hsked & nice_icb_rsp_err)
   //                          | (nice_req_hsked & illgel_instr)
   //                          ; 
   assign nice_rsp_err   =   (nice_icb_rsp_hsked & nice_icb_rsp_err);

11、memory相关

1)nice_icb_rsp_ready始终为1'b1

2)sbuf_idx为subf_cmd_cnt_r

3)nice_icb_cmd_valid,(当前状态为idle且E203发出nice_req_valid且指令有效)或(状态lbuf,lbuf计数值小于最后值)或(状态sbuf,sbuf_cmd小于等于最后值且sbuf计数值不是最后值)或(状态rowsum,rcv_data_buf计数值小于最后值,且(rcv_data_buf_idx非零,且上个周期的状态为rowsum时(储存响应握手或E203发出nice_rsp_ready信号))

4)nice_icb_cmd_addr,(状态idle且命令有效)为寄存器1,否则为maddr_acc_r

5)nice_icb_cmd_read,(状态idle且为lbuf或rowsumz指令,为1,为sbuf指令,为0),或者为sbuf状态为0,否则为1

6)nice_icb_cmd_wdata,(状态idle,sbuf指令)或subf状态,为rowbuf_r[sbuf_idx],否则为0

7)nice_icb_cmd_size,为2,代表4字节32位宽数据

8)nice_mem_holdup,为非idle状态,访问memory锁

 // rsp always ready
   assign nice_icb_rsp_ready = 1'b1; 
   wire [ROWBUF_IDX_W-1:0] sbuf_idx = sbuf_cmd_cnt_r; 

   assign nice_icb_cmd_valid =   (state_is_idle & nice_req_valid & custom_mem_op)
                              | nice_icb_cmd_valid_lbuf
                              | nice_icb_cmd_valid_sbuf
                              | nice_icb_cmd_valid_rowsum
                              ;
   assign nice_icb_cmd_addr  = (state_is_idle & custom_mem_op) ? nice_req_rs1 :
                              maddr_acc_r;
   assign nice_icb_cmd_read  = (state_is_idle & custom_mem_op) ? (custom3_lbuf | custom3_rowsum) : 
                              state_is_sbuf ? 1'b0 : 
                              1'b1;
   assign nice_icb_cmd_wdata = (state_is_idle & custom3_sbuf) ? rowbuf_r[sbuf_idx] :
                              state_is_sbuf ? rowbuf_r[sbuf_idx] : 
                              `E203_XLEN'b0; 

   //assign nice_icb_cmd_wmask = {`sirv_XLEN_MW{custom3_sbuf}} & 4'b1111;
   assign nice_icb_cmd_size  = 2'b10;
   assign nice_mem_holdup    =  state_is_lbuf | state_is_sbuf | state_is_rowsum; 

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:58:47  更:2022-04-18 18:01:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:27:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码