d:/e203_bd_xc7z/e203_bd_3eg/IP/nice_core/src/nice_core.v
`include "e203_defines.v" // 包含E203核心的全屿定义
`ifdef E203_HAS_NICE//{ // 条件编译,仅在定义了NICE协处理器时编诿
module nice_core (
// System 系统
input nice_clk , // 协处理器时钟
input nice_rst_n , // 低有效复位信叿
output nice_active , // 协处理器活动状濁指礿
output nice_mem_holdup , // 保持内存总线信号
// output nice_rsp_err_irq ,
// Control cmd_req 控制命令请求通道
(* mark_debug = "true" *)input nice_req_valid , // 请求有效
(* mark_debug = "true" *)output nice_req_ready , // 请求就绪
(* mark_debug = "true" *)input [`E203_XLEN-1:0] nice_req_inst , // 指令内容
(* mark_debug = "true" *)input [`E203_XLEN-1:0] nice_req_rs1 , // 源操作数1
(* mark_debug = "true" *)input [`E203_XLEN-1:0] nice_req_rs2 , // 源操作数2
// Control cmd_rsp 控制命令响应通道
(* mark_debug = "true" *)output nice_rsp_valid , // 响应有效
input nice_rsp_ready , // 响应就绪
output [`E203_XLEN-1:0] nice_rsp_rdat , // 结果数据
output nice_rsp_err , // 错误指示
// *内存访问通道,暂时没有用刿***
// Memory lsu_req 内存访问命令通道(ICB总线_
output nice_icb_cmd_valid , // 命令有效
input nice_icb_cmd_ready , // 命令就绪
output [`E203_ADDR_SIZE-1:0] nice_icb_cmd_addr , // 访问地址
output nice_icb_cmd_read , // 读使胿
output [`E203_XLEN-1:0] nice_icb_cmd_wdata , // 写数捿
// output [`E203_XLEN_MW-1:0] nice_icb_cmd_wmask , //
output [1:0] nice_icb_cmd_size , // 访问大小
// Memory lsu_rsp
input nice_icb_rsp_valid , // 响应有效
output nice_icb_rsp_ready , // 响应就绪
input [`E203_XLEN-1:0] nice_icb_rsp_rdata , // 读数捿
input nice_icb_rsp_err , // 访问错误
//test port
output led_out,
output [31:0] gpio_led_0
);
wire [31:0] gpio_led_1;
assign gpio_led_0 = gpio_led_1;
// output declaration of module nice_decode
wire custom0_trigger_start;
wire custom0_test;
//nice 解码
nice_decode u_nice_decode(
.nice_req_valid (nice_req_valid ),
.nice_req_inst (nice_req_inst ),
.custom0_test (custom0_test),
.custom0_trigger_start(custom0_trigger_start)
);
test_instr u_test_instr(
.clk (nice_clk),
.rst_n (nice_rst_n),
.test_req_valid (custom0_test),
.test_req_ready (nice_req_ready),
.test_req_rs1 (nice_req_rs1),
.test_req_rs2 (nice_req_rs2),
.test_rsp_valid (nice_rsp_valid),
.test_rsp_ready (nice_rsp_ready),
.test_rsp_rdat (nice_rsp_rdat),
.led_out (led_out),
.gpio_led (gpio_led_1)
);
endmodule
`endif//}
d:/e203_bd_xc7z/e203_bd_3eg/IP/nice_core/src/nice_decode.v
`include "e203_defines.v" // 包含E203核心的全屿定义
module nice_decode(
input nice_req_valid , // 请求有效
input [`E203_XLEN-1:0] nice_req_inst , // 指令内容
output custom0_test,
output custom0_trigger_start
);
//*decode***
// 提取指令字段
wire [6:0] opcode = {7{nice_req_valid}} & nice_req_inst[6:0];
wire [2:0] rv32_func3 = {3{nice_req_valid}} & nice_req_inst[14:12];
wire [6:0] rv32_func7 = {7{nice_req_valid}} & nice_req_inst[31:25];
// oopcode 解码
wire opcode_custom0 = (opcode == 7'h0b);
wire opcode_custom1 = (opcode == 7'h2b);
wire opcode_custom2 = (opcode == 7'h5b);
wire opcode_custom3 = (opcode == 7'h7b);
// 功能3解码
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);
// 功能7解码
wire rv32_func7_0 = (rv32_func7 == 7'd0);
wire rv32_func7_1 = (rv32_func7 == 7'd1);
wire rv32_func7_2 = (rv32_func7 == 7'd2);
wire rv32_func7_3 = (rv32_func7 == 7'd3);
wire rv32_func7_4 = (rv32_func7 == 7'd4);
wire rv32_func7_5 = (rv32_func7 == 7'd5);
wire rv32_func7_6 = (rv32_func7 == 7'd6);
wire rv32_func7_7 = (rv32_func7 == 7'd7);
// multi-cyc op 多周期操作检浿
// wire custom_multi_cyc_op = |custom0_i2f|custom0_f2i|custom0_add|custom0_sub|custom0_multi|custom0_divid|custom0_trigger_start; //是否为多周期操作
wire custom_multi_cyc_op = custom0_test|custom0_trigger_start; //是否为多周期操作
// need access memory 是否霿要访问内孿
wire custom_mem_op ;
//*control custom***
assign custom0_test = opcode_custom0 & rv32_func3_011 & rv32_func7_0;
assign custom0_trigger_start = opcode_custom0 & rv32_func3_000 & rv32_func7_7;
endmodule //nice_decode
d:/e203_bd_xc7z/e203_bd_3eg/IP/nice_core/src/test_instr.v
`include "e203_defines.v"
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/05/21 16:07:39
// Design Name:
// Module Name: test_instr
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module test_instr(
input clk ,
input rst_n ,
input test_req_valid , //在decode中识别该条指令的有效信号 等价于 nice_req_valid
output test_req_ready ,
input [`E203_XLEN-1:0] test_req_rs1 ,
input [`E203_XLEN-1:0] test_req_rs2 ,
output test_rsp_valid ,
input test_rsp_ready ,
output [`E203_XLEN-1:0] test_rsp_rdat ,
(* mark_debug = "true" *)output led_out,
(* mark_debug = "true" *)output [31:0] gpio_led
);
reg [31:0] gpio_led_0;
// 状态定义
parameter IDLE = 2'b00;
parameter EXEC = 2'b01;
parameter RESP = 2'b10;
(* mark_debug = "true" *)reg [1:0] state;
reg [1:0] next_state;
reg [31:0] freq_counter;
reg [31:0] time_counter;
reg [31:0] led_freq;
reg [31:0] led_time;
reg led;
reg exec_done;
reg r_test_req_ready;
reg r_test_rsp_valid;
reg [`E203_XLEN-1:0] r_test_rsp_rdat ;
// 状态转移逻辑
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= next_state;
end
// 状态机:下一个状态逻辑
always @(*) begin
case (state)
IDLE: next_state = (test_req_valid) ? EXEC : IDLE;
EXEC: next_state = (exec_done) ? RESP : EXEC;
RESP: next_state = (test_rsp_ready) ? IDLE : RESP;
default: next_state = IDLE;
endcase
end
// 主功能逻辑
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
r_test_req_ready <= 0;
r_test_rsp_valid <= 0;
r_test_rsp_rdat <= 0;
freq_counter <= 0;
time_counter <= 0;
led_freq <= 0;
led_time <= 0;
led <= 0;
exec_done <= 0;
gpio_led_0 <= 0;
end else begin
case (state)
IDLE: begin
r_test_rsp_valid <= 0;
exec_done <= 0;
if ((test_req_valid==1'b1) && (r_test_rsp_valid==1'b0)) begin
led_freq <= test_req_rs1;
led_time <= test_req_rs2;
r_test_req_ready <= 1;
freq_counter <= 0;
time_counter <= 0;
led <= 0;
end
end
EXEC: begin
r_test_req_ready <= 0;
if (time_counter < led_time) begin
freq_counter <= freq_counter + 1;
if (freq_counter >= led_freq) begin
freq_counter <= 0;
led <= ~led; // 翻转LED状态
gpio_led_0 <= ~gpio_led_0;
end
time_counter <= time_counter + 1;
end else begin
exec_done <= 1;
// r_test_rsp_rdat <= led; // 返回LED最终状态
end
end
RESP: begin
r_test_rsp_valid <= 1;
if (test_rsp_ready && r_test_rsp_valid) begin
r_test_rsp_valid <= 0;
end
end
endcase
end
end
assign test_req_ready = r_test_req_ready;
assign test_rsp_valid = r_test_rsp_valid;
assign test_rsp_rdat = r_test_rsp_rdat ;
// 输出到引脚的LED信号(可选)
assign led_out = led;
assign gpio_led = gpio_led_0;
endmodule
打开给定的Vivado项目,双击design_1_i,可以看到设计文件,我们右键选择Edit in IP Packager可以看到我们的nice core ip核的源代码
硬件侧:
协处理器模块:nice_core
子模块:
nice_decode:解码自定义指令。关键代码:
assign custom0_test = opcode_custom0 & rv32_func3_011 & rv32_func7_0;
test_instr.v:实现具体的LED控制逻辑:
状态机设计:
IDLE:等待指令请求,捕获输入参数(led_freq和led_time)。
EXEC:根据led_freq周期性翻转LED状态(freq_counter计数)。通过time_counter累计总持续时间,超时后进入RESP状态。
RESP:向CPU返回响应(当前LED状态)。
关键信号:
led_out:直接控制LED引脚的电平。
gpio_led:32位GPIO输出控制32个led灯。
软件侧:
核心自定义指令:
__STATIC_FORCEINLINE int custom_test(int led_freq, int led_time) {
asm volatile (
".insn r 0xB, 3, 0, %[rd], %[rs1], %[rs2]" // opcode=0xB, func3=3, func7=0
: [rd] "=r" (res)
: [rs1] "r" (led_freq), [rs2] "r" (led_time)
);
return res;
}
指令编码:
opcode=0x0B:RISC-V自定义指令0(Custom-0)的编码。
func3=0b011:区分不同功能(此处为LED控制)。
func7=0:进一步细分操作类型。
参数传递:
led_freq(rs1):LED闪烁频率(时钟周期数)。
led_time(rs2):LED总持续时间(时钟周期数)。
我要的效果是图片中的1-32led灯从右往左顺序闪烁,实现跑马灯,这个只提交.bit每次只亮一个灯:在任意时刻只有一个灯亮,灯的位置依次移动。
我使用的是vivado 2020