一、端口说明

// 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_reqinput                         nice_req_valid       ,//E203 send a nice requestoutput                        nice_req_ready       ,//nice can receive requestinput  [`E203_XLEN-1:0]       nice_req_inst        ,//custom instructioninput  [`E203_XLEN-1:0]       nice_req_rs1         ,//the register 1input  [`E203_XLEN-1:0]       nice_req_rs2         ,//the register 2// Control cmd_rsp   output                        nice_rsp_valid       ,//nice send responseinput                         nice_rsp_ready       ,//e203 can receive responseoutput [`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 requestinput                         nice_icb_cmd_ready   ,//e203 can receive memory requestoutput [`E203_ADDR_SIZE-1:0]  nice_icb_cmd_addr    ,//memory request addressoutput                        nice_icb_cmd_read    ,//0:write 1:read output [`E203_XLEN-1:0]       nice_icb_cmd_wdata   ,//write data requestoutput [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 responseoutput                        nice_icb_rsp_ready   ,//nice can receive memoryinput  [`E203_XLEN-1:0]       nice_icb_rsp_rdata   ,//the data read from memoryinput                         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  func7 32位的指令 读取 写回
custom3_lbuf 3'h2 7'h01 {7'h01,10'hxx,3'h2,5'hxx,7'h7b} rs1
custom3_sbuf 3'h2 7'h02 {7'h02,10'hxx,3'h2,5'hxx,7'h7b} rs1
custom3_rowsum 3'h6 7'h06 {7'h06,10'hxx,3'h6,5'hxx,7'h7b} rs1 rd

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

  //  multi-cyc op wire custom_multi_cyc_op = custom3_lbuf | custom3_sbuf | custom3_rowsum;//the instrution is made by nice// need access memorywire 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 LBUFassign 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 LBUFassign 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_clr sbuf_icb_rsp_hsked_last
sbuf_cnt_incr sbuf_cnt增加,使能
sbuf_cnt_ena D触发器,使能
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 SBUFassign 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_r sbuf_cmd现计数值
sbuf_cmd_cnt_nxt sbuf_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_last sbuf_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 SBUFassign 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 LBUFassign 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_r 4个32位的数据
rowbuf_wdata 4个32位的数据
rowbuf_we 4位宽的数据
rowbuf_idx_mux rowbuf的序号选择
rowbuf_wdata_mux rowbuf的写入数据选择
rowbuf_wr_mux rowbuf的写入信号选择
lbuf_dix lbuf写入的序号
lbuf_wr lbuf写入的使能
lbuf_wdata lbuf写入的数据
rowsum_idx rowsum写入的序号
rcv_data_buf_valid rowsum写入的使能
rowsum_wdata rowsum写入的数据

②信号赋值

写入的选择

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 rowbufwire [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 muxassign 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 instgenvar i;generate for (i=0; i<ROWBUF_DP; i=i+1) begin:gen_rowbufassign 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);endendgenerate

9、memory的地址

①信号说明

nice_icb_cmd_hsked 储存请求握手
lbuf_maddr_ena lbuf,访问memory的使能
sbuf_maddr_ena sbuf,访问memory的使能
rowsum_maddr_ena rowsum,访问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 reusedwire [`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_reqassign 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_rspassign 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 readyassign 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; 

NICE的Verilog代码相关推荐

  1. Verilog代码规范I

    Verilog代码规范I "规范"这问题 "规范"这个富含专业气息的词汇(个人感觉),其实规范这种东西,就是大家都约定熟成的东西,一旦你不遵守这个东西,专业人士 ...

  2. FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析

    FPGA学习之路--原码二位乘法器及Verilog代码分析 原理 原码乘法可以分为原码一位乘和原码二位乘,两者在实现规则上大同小异.原码一位乘每次判断乘数的最低位,对被乘数和部分积进行相应操作.而原码 ...

  3. 网页版的svn怎样同步代码_学会使用Hdlbits网页版Verilog代码仿真验证平台

    大家推荐一款网页版的 Verilog代码编辑仿真验证平台,这个平台是国外的一家开源FPGA学习网站,通过 "https://hdlbits.01xz.net/wiki/Main_Page&q ...

  4. (67)FPGA面试题-为priority encoder编写Verilog代码,实现MUX4_1

    1.1 FPGA面试题-为priority encoder编写Verilog代码,实现MUX4_1 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-为pr ...

  5. (66)FPGA面试题-为parallel encoder编写Verilog代码,实现MUX4_1

    1.1 FPGA面试题-为parallel encoder编写Verilog代码,实现MUX4_1 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-为pa ...

  6. 4位7段共阴数码管动态显示的verilog代码

    4位7段共阴数码管动态显示的verilog代码 sn_data为输入的显示数值 clk接100MHz时钟 s为数码管位选信号,高电平有效 seg为7段共阴极数码管输出 `timescale 1ns / ...

  7. 基于多相滤波器的数字信道化算法详解(Python, Verilog代码已开源)

    基于多相滤波器的数字信道化算法详解 推导过程 总结 仿真 本文详细介绍了基于多相滤波器的数字信道化算法的推导过程, 如果您在阅读的过程中发现算法推导过程中有任何错误, 请不吝指出. 此外, 进入我的G ...

  8. 异步FIFO设计:各个模块的作用及Verilog代码详解

    实现原理参考:异步FIFO---Verilog实现_alangaixiaoxiao的博客-CSDN博客_异步fifo 代码参考:IC基础(一):异步FIFO_MaoChuangAn的博客-CSDN博客 ...

  9. 异步FIFO的原理以及可综合的Verilog代码

    异步FIFO的原理以及可综合的Verilog代码 一.FIFO的定义 二.FIFO的应用场景 三.FIFO的分类 FIFO的参数 FIFO的设计难点 一.FIFO的定义 _ First In Firs ...

  10. 异步FIFO的verilog代码实现(包含将满和将空逻辑)

    目录 异步FIFO的verilog代码实现(包含将满和将空逻辑) 异步FIFO简介 异步FIFO关键技术1 -- 读写信号跨时钟域同步 异步FIFO关键技术2 -- 读写地址的比较 异步FIFO关键技 ...

最新文章

  1. HSSFWorkbook 与 XSSFWorkbook
  2. Tornado 学习笔记
  3. git 基本命令记录
  4. PHP面试题:PHP加速模式/扩展? PHP调试模式/工具?
  5. 如何在SAP Spartacus里监控用户浏览了某产品明细页面的动作
  6. C/C++ ini配置文件的格式及如何读写ini配置文件
  7. 一百馒头一百僧,大僧三个更无争,小僧三人分一个大小和尚得几丁?
  8. oracle 11g 组合分区,Oracle数据库
  9. ubuntu17安装mysql后数据库乱码_linux安装MySQL数据库,设置编码为utf8
  10. mysql 常用操作(整理)
  11. 190227每日一句
  12. raw数据恢复之raw格式硬盘如何恢复数据?
  13. RHEL7的安装步骤
  14. Telink BDT 的使用方法
  15. c语言学习笔记(7)单引号,双引号和逻辑符号的用法
  16. 【NGUI】实现半圆形进度条,技能CD效果
  17. 教你如何拍好人像摄影
  18. java拼图游戏ai_拼图游戏和它的AI算法
  19. 怎样一键比较2个CAD图纸文件的不同呢?
  20. 软件测试助理利弊,女生做软件测试的利弊都有什么?

热门文章

  1. Mac的esc键失效的解决方法
  2. 【读书笔记】凤凰架构-事务处理
  3. EEG- gan:用于脑电图(EEG)大脑信号的生成对抗网络2018
  4. 【FPGA】十一、I2C通信回环
  5. 【V2ray 报错 failed to read response header】
  6. 中国996外资955曝光,有你家公司吗?
  7. OpenCV图像高光
  8. 全靠这份Java知识点PDF大全,先睹为快
  9. 快速填充表格中的空单元格
  10. jquery实现滑动滚动条出现对联广告