硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4748|回复: 1
收起左侧

Verilog设计练习进阶(9)-------利用状态机的嵌套实现层次结构化设计

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107418
QQ
发表于 2013-1-31 09:29:49 | 显示全部楼层 |阅读模式
说明:此程序有错,所以放在也是错误的,不过不影响状态机的学习。
module verilog_prj(reset,clk,address,data,sda,ack);
  input reset,clk;
  input[7:0] data,address;
   
  output sda,ack;  //sda 负责串行数据输出;
             //ack是一个对象操作完毕后,模块给出的应答信号。
  reg link_write;  //link_write  决定何时输出。
  reg[3:0] state;  //主状态机的状态字。
  reg[4:0] sh8out_state;  //从状态机的状态字。
  reg[7:0] sh8out_buf;    //输入数据缓冲。
  reg finish_F;           //用以判断是否处理完一个操作对象。
  reg ack;
   
  parameter
    idle=0,addr_write=1,data_write=2,stop_ack=3;
  parameter
    bit0=1,bit1=2,bit2=3,bit3=4,bit4=5,bit5=6,bit6=7,bit7=8;  
   
  assign   sda = link_write? sh8out_buf[7] : 1'bz;
   
  always @(posedge clk)
    begin
     if(!reset)               //复位。
       begin
          link_write<= 0;
          state    <= idle;
          finish_F <= 0;
          sh8out_state<=idle;
                ack<= 0;
          sh8out_buf<=0;
       end
     else
       case(state)
        
       idle:                        
         begin
          link_write  <= 0;
            state    <= idle;
            finish_F <= 0;
            sh8out_state<=idle;
                  ack<= 0;
            sh8out_buf<=address;   
           state    <= addr_write;
         end
             addr_write:         //地址的输入。
         begin
          if(finish_F==0)
            begin  shift8_out; end
          else
            begin
               sh8out_state <= idle;
               sh8out_buf   <= data;
                      state <= data_write;
                   finish_F <= 0;
            end
         end
        
       data_write:       //数据的写入。
         begin
          if(finish_F==0)  
            begin  shift8_out; end
          else
            begin
                link_write <= 0;
                     state <= stop_ack;
                  finish_F <= 0;   
                       ack <= 1;
            end
         end   
        
       stop_ack:             //完成应答。
         begin
            ack <= 0;
           state <= idle;
         end
        
       endcase        
    end                        
              
task shift8_out;                //串行写入。
  begin
     case(sh8out_state)
      
     idle:  
       begin
          link_write  <= 1;
         sh8out_state <= bit0;
                  end
      
     bit0:
       begin
           link_write <= 1;
         sh8out_state <= bit1;                                   
           sh8out_buf <= sh8out_buf<<1;
       end
      
     bit1:
       begin
         sh8out_state<=bit2;
         sh8out_buf<=sh8out_buf<<1;
       end
        
     bit2:
       begin
         sh8out_state<=bit3;
         sh8out_buf<=sh8out_buf<<1;
       end
      
     bit3:
       begin
         sh8out_state<=bit4;
         sh8out_buf<=sh8out_buf<<1;
       end
      
     bit4:
       begin
         sh8out_state<=bit5;
         sh8out_buf<=sh8out_buf<<1;
       end
      
     bit5:
       begin
         sh8out_state<=bit6;
         sh8out_buf<=sh8out_buf<<1;
       end
      
     bit6:
       begin
         sh8out_state<=bit7;
         sh8out_buf<=sh8out_buf<<1;
       end
               
     bit7:
       begin
         link_write<= 0;
         finish_F<=finish_F+1;               
       end   
        
     endcase
  end
endtask

endmodule        
测试模块
`timescale 1 ns/ 1 ps
`define clk_cycle 50
module verilog_prj_vlg_tst();

// test vector input registers
reg [7:0] address;
reg clk;
reg [7:0] data;
reg reset;
// wires                                               
wire ack;
wire sda;

// assign statements (if any)                          
verilog_prj i1 (
// port map - connection between master ports and signals/registers   
    .ack(ack),
    .address(address),
    .clk(clk),
    .data(data),
    .reset(reset),
    .sda(sda)
);
  always #`clk_cycle  clk = ~clk;
   
  initial
    begin
       clk=0;
       reset=1;
       data=0;
       address=0;
       #(2*`clk_cycle) reset=0;
       #(2*`clk_cycle) reset=1;
       #(100*`clk_cycle) $stop;
    end
     
  always @(posedge ack)      // 接收到应答信号后,给出下一个处理对象。
    begin
       data=data+1;
       address=address+1;
    end                                                   
endmodule
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107418
QQ
 楼主| 发表于 2013-1-31 09:34:11 | 显示全部楼层
1.jpg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-31 00:38 , Processed in 0.182019 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表