随便贴一个自己用VERILOG写的状态机

54 篇文章 5 订阅
46 篇文章 8 订阅

有这样写VERILOG风格吗?类似风格好像我没有见过别人写过。我只是为了简洁,写得快,就有了这种FSM串行序列执行的的写法。感觉难度介于汇编和C之间。运行效果也很好,就暂时没有进行优化和替换。


/*


module tb_cfg_FSM;

 
reg clk,rst,valid;
reg [23:0]  ins ;


initial begin  
{clk,rst,valid}=0;
rst = 1;
#100 rst = 0; 

 


#100000; $finish ;



end  
CFG_FSM   cfg_FSM  (
.clk(clk),
.rst(rst),
.valid(valid) ,
.ready(ready),
.ins(ins),
.error(error),
.spi_mosi(spi_mosi),
.spi_clk(spi_clk),
.spi_csn(spi_csn),
.spi_miso(spi_miso)
);

endmodule

*/




module CFG_FSM #(parameter FRQ = 100*1000*1000)(
        input clk,rst,
        input valid ,
        output reg ready,
        input [23:0] ins,
        output reg error,
        output [7:0]dout,
        output   spi_mosi,spi_clk,spi_csn,
        input spi_miso
    );

    reg [7:0]  st      ;
    reg [23:0] insr    ;
    reg [2:0]  op_type ;
    //0   write reg
    //1   read reg
    //2   wait time
    //3   wait a bit

    always @ (posedge clk)if (st==3)begin
            if (insr[23]==1) op_type = 0; // write
            else case (insr[22:20])
                0 : op_type = 1 ;
                1 : op_type = 2 ;
                2 : op_type = 3 ;
                3 : op_type = 4 ;
                default op_type = 'hx ;
            endcase end

    wire [23:0]  cmd24bit  = {insr[23],3'b000,insr[19:0]};

    reg [15:0] ms_tmr ;

  wire ms_of =  ms_tmr == (FRQ/1000-1) ;
  //    wire ms_of =  ms_tmr == (10-1) ;
 
	reg ms_state = 0 ;
	always@*case (st)	121,130,131,132,133,134,135 ,136: ms_state=1;default ms_state=0;endcase
	
	always @ (posedge clk) if (ms_state)ms_tmr<= ( ms_of ) ?0 :1+ms_tmr;else ms_tmr<=0;
	//always@(posedge clk) if (ms_state)ms_tmr<=  1+ms_tmr;else ms_tmr<=0;


    reg [15:0]  ms_cnt;
    always @ (posedge clk) if (ms_state) ms_cnt<=(ms_of)?ms_cnt+1:ms_cnt; else ms_cnt<=0;

    reg FSM_valid ;
    reg [7:0] read_value ;
    wire[7:0] FSM_dout ;

	wire if_n_zero = (read_value & (1<<insr[2:0])) !=0  ; 
	
    always @ (posedge clk)
        if (rst) st<=0;else case (st)
        0:begin ready<=0; FSM_valid<=0;st<=1;error<=0;end
        1:if (valid) begin ready<=0; error<=0;st<=2;end
        2:begin st<=3;insr<=ins;end   //store this instruction
        3:st<=4; //decode
        4:case  (op_type)
            0:st<=100;// write reg
            1:st<=110;// read reg
            2:st<=120;// wait ms
            3:st<=130;// check a bit
            default  st<=0;
        endcase

    100: begin st<=101;FSM_valid<=1;end
        101: begin  FSM_valid<=0;st<=102;end
        102:st<=103;
        103:st<=104;
        104: if  (FSM_ready)    st<=105;
    105: st<=106;
    106: st<=200; // endof write  reg

110: begin st<=111;FSM_valid<=1;end
    111: begin  FSM_valid <=0; st<=112; end
    112: st <= 113 ;
    113: st <= 114 ;
    114: if  (FSM_ready)    st<=115;
115: begin read_value <= FSM_dout ; st <= 116 ;  end
116: st <= 200 ; // endof read  reg

120: st<=121;
121: if (ms_cnt[15:0]==insr[15:0])  st<=122;
122: st <= 123 ;
123: st <= 200; // wait time

130: begin st<=131;FSM_valid<=1;end
131: begin  FSM_valid <= 0 ; st<=132;end
132: st<=133;
133: st<=134;
134: if  (FSM_ready)    st<=135; else if (ms_cnt[15:0] >= 2000 ) st<=160;
135: begin read_value <= FSM_dout ; st <= 136;  end
136: case ({insr[7],if_n_zero})2'b00 ,2'b11: st<=137;default st<=130 ;endcase 
137: st<=200 ;  // return ok, check a bit and wait

160: begin error<=1;st<=1;end
200: begin ready<=1;st<=1;end

default  st<=0;
endcase

assign  dout = FSM_dout ;
spi_ad9361_if  #( .cnt_bit(3) ) spi_ad9361_if (
                   .clk  ( clk ),
                   .rst  ( rst  ),
                   .spi_mosi ( spi_mosi ),
                   .spi_clk ( spi_clk),
                   .spi_csn (  spi_csn),
                   .spi_miso ( spi_miso ),
                   .din ( cmd24bit ),
                   .dout (  FSM_dout ) ,
                   .valid ( FSM_valid ) ,
                   .ready ( FSM_ready )
               );

endmodule



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴为您解答Verilog状态机的问题。Verilog状态机是通过always语句来实现的。以下是一个简单的Verilog状态机实例代码: ``` module state_machine(input clk, input reset, output reg state); // 定义状态常量 parameter S_IDLE = 1'b0; parameter S_WAIT = 1'b1; parameter S_DONE = 1'b2; // 定义状态变量 reg [1:0] current_state, next_state; // 状态转移逻辑 always @(posedge clk or posedge reset) begin if (reset) current_state <= S_IDLE; else current_state <= next_state; end // 状态机行为逻辑 always @(current_state) begin case (current_state) S_IDLE: begin // 进入空闲状态 // 设置下一个状态为等待状态 next_state <= S_WAIT; end S_WAIT: begin // 进入等待状态 // 如果某些条件满足,设置下一个状态为完成状态 if (/*某些条件*/) next_state <= S_DONE; else next_state <= S_WAIT; end S_DONE: begin // 进入完成状态 // 设置下一个状态为空闲状态 next_state <= S_IDLE; end default: begin next_state <= S_IDLE; end endcase end // 输出逻辑 always @(current_state) begin case (current_state) S_IDLE: begin state <= 1'b0; end S_WAIT: begin state <= 1'b0; end S_DONE: begin state <= 1'b1; end default: begin state <= 1'b0; end endcase end endmodule ``` 以上是一个简单的状态机,其中有三个状态:空闲状态、等待状态和完成状态。状态机通过始终语句进行状态转移,通过cases语句实现状态机行为逻辑和输出逻辑。注意,此示例仅用于说明状态机的基本概念和语法,您应该根据需要进行修改和扩展。希望能够帮助您解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值