在verilog中自动增加案例状态
Increment case state automatically in verilog
我想编写一个可综合的状态机,read/write wishbone 命令按顺序排列。
目前我定义了一些verilog宏:
`define WB_READ(READ_ADDR) \
begin \
wb_addr_o <= UART_DIV;\
wb_stb_o <= 1'b1; wb_cyc_o <= 1'b1; wb_we_o <= 1'b0; end
`define WB_WRITE(WR_ADDR, WVALUE) \
begin \
wb_addr_o <= WR_ADDR;\
wb_wdat_o <= WVALUE;\
wb_stb_o <= 1'b1; wb_cyc_o <= 1'b1; wb_we_o <= 1'b1; end\
`define WB_NOPE \
begin\
wb_stb_o <= 1'b0; wb_cyc_o <= 1'b0; wb_we_o <= 1'b0; end
并在我的 FSM 过程中使用:
always @(posedge clk or posedge rst)
if(rst) begin
count <= 8'h00;
wb_addr_o <= 8'h00;
wb_wdat_o <= 8'h00;
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
wb_we_o <= 1'b0;
end
else begin
case(count)
{7'h01, 1'b1}: `WB_READ(UARD_DIV)
{7'h02, 1'b1}: `WB_READ(UARD_DIV)
{7'h03, 1'b1}: `WB_WRITE(UART_LCR, 8'h60)
{7'h04, 1'b1}: `WB_WRITE(UART_DIV, 8'h01)
{7'h05, 1'b1}: `WB_WRITE(UART_THR, 8'h55)
default: `WB_NOPE
endcase
if (count < {7'h06, 1'b1})
count <= count + 1;
end
每次计数为偶数,WB_NOPE状态为“已执行”,每次为奇数,执行给定的命令。
这在模拟中有效,但如果我想在状态机中间添加命令,我必须重新缩进所有 {7'hxx, 1'b1} 状态。并在末尾增加 if(count < ...)。
有人知道如何改进这个(用宏吗?)以避免它?
您可以在 case 语句中只使用一个整数值,并在每个步骤中增加它。这是你的代码的一个稍微精简的版本,它可以做你想要的(或者至少是足够接近你可以修复它的东西:-))
module testcase (input logic clk,input logic rst);
enum logic [1:0] { READ,WRITE,NOP } op;
logic [7:0] count;
`define WB_READ begin op <= READ; end
`define WB_WRITE begin op <= WRITE; end
`define WB_NOPE begin op <= NOP; end
logic [6:0] fsm_step_number;
always @(posedge clk or posedge rst)
if(rst) begin
count <= 8'h00;
op <= NOP;
end
else begin
fsm_step_number=1;
case(count)
{(fsm_step_number++), 1'b1}: `WB_READ
{(fsm_step_number++), 1'b1}: `WB_READ
{(fsm_step_number++), 1'b1}: `WB_WRITE
{(fsm_step_number++), 1'b1}: `WB_WRITE
{(fsm_step_number++), 1'b1}: `WB_WRITE
default: `WB_NOPE
endcase
if (count < {(fsm_step_number), 1'b1})
count <= count + 1;
end
assert
endmodule
我想编写一个可综合的状态机,read/write wishbone 命令按顺序排列。
目前我定义了一些verilog宏:
`define WB_READ(READ_ADDR) \
begin \
wb_addr_o <= UART_DIV;\
wb_stb_o <= 1'b1; wb_cyc_o <= 1'b1; wb_we_o <= 1'b0; end
`define WB_WRITE(WR_ADDR, WVALUE) \
begin \
wb_addr_o <= WR_ADDR;\
wb_wdat_o <= WVALUE;\
wb_stb_o <= 1'b1; wb_cyc_o <= 1'b1; wb_we_o <= 1'b1; end\
`define WB_NOPE \
begin\
wb_stb_o <= 1'b0; wb_cyc_o <= 1'b0; wb_we_o <= 1'b0; end
并在我的 FSM 过程中使用:
always @(posedge clk or posedge rst)
if(rst) begin
count <= 8'h00;
wb_addr_o <= 8'h00;
wb_wdat_o <= 8'h00;
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
wb_we_o <= 1'b0;
end
else begin
case(count)
{7'h01, 1'b1}: `WB_READ(UARD_DIV)
{7'h02, 1'b1}: `WB_READ(UARD_DIV)
{7'h03, 1'b1}: `WB_WRITE(UART_LCR, 8'h60)
{7'h04, 1'b1}: `WB_WRITE(UART_DIV, 8'h01)
{7'h05, 1'b1}: `WB_WRITE(UART_THR, 8'h55)
default: `WB_NOPE
endcase
if (count < {7'h06, 1'b1})
count <= count + 1;
end
每次计数为偶数,WB_NOPE状态为“已执行”,每次为奇数,执行给定的命令。
这在模拟中有效,但如果我想在状态机中间添加命令,我必须重新缩进所有 {7'hxx, 1'b1} 状态。并在末尾增加 if(count < ...)。
有人知道如何改进这个(用宏吗?)以避免它?
您可以在 case 语句中只使用一个整数值,并在每个步骤中增加它。这是你的代码的一个稍微精简的版本,它可以做你想要的(或者至少是足够接近你可以修复它的东西:-))
module testcase (input logic clk,input logic rst);
enum logic [1:0] { READ,WRITE,NOP } op;
logic [7:0] count;
`define WB_READ begin op <= READ; end
`define WB_WRITE begin op <= WRITE; end
`define WB_NOPE begin op <= NOP; end
logic [6:0] fsm_step_number;
always @(posedge clk or posedge rst)
if(rst) begin
count <= 8'h00;
op <= NOP;
end
else begin
fsm_step_number=1;
case(count)
{(fsm_step_number++), 1'b1}: `WB_READ
{(fsm_step_number++), 1'b1}: `WB_READ
{(fsm_step_number++), 1'b1}: `WB_WRITE
{(fsm_step_number++), 1'b1}: `WB_WRITE
{(fsm_step_number++), 1'b1}: `WB_WRITE
default: `WB_NOPE
endcase
if (count < {(fsm_step_number), 1'b1})
count <= count + 1;
end
assert
endmodule