夏宇闻复习笔记第13章:设计可综合状态机的指导原则

异步信号数据接口的同步

(1)RAM或FIFO进行缓存再读取
(3)两级触发器同步化

(2)数据帧头位置确定方法:增加一条帧头标志信号线,或在数据头插入一段特殊码型的同步码到接收端以监测帧头
在这里插入图片描述

case中default设置的问题

在这里插入图片描述

p179 13.1 宇宙飞船控制器
/******************************p179 13.1 宇宙飞船控制器********************************/
module  fsm(launch_shuttle,land_shuttle,start_countdowns,start_trip_meter,clk,all_system_go,just_launched,is_landed,cnt,rst_n,state_c);

input       just_launched,is_landed,all_system_go;//输入的操作指令,也即是case转换的依据
input       rst_n;//复位
input       clk;
input       [3:0]   cnt;
output  reg [4:0]   state_c;
reg         [4:0]   state_n; 
output  reg land_shuttle,launch_shuttle,start_countdowns,start_trip_meter;//输出
 
parameter   HOLD        =   5'b00001,
            SEQUENCE    =   5'b00010,
            LAUNCH      =   5'b00100,
            ON_MISSION  =   5'b01000,
            LAND        =   5'b10000;

//状态转换       
always@(posedge clk or negedge rst_n)   begin
    if(!rst_n)  state_c   <=  LAND;
    else        state_c   <=  state_n;
end

//next状态的case设置为组合逻辑
always@(*)   begin
    case(state_c) 
        HOLD:       if(state_c==HOLD && all_system_go)      state_n  =   SEQUENCE;  
                    else                                    state_n  =   state_c; 
                    
        SEQUENCE:   if(state_c==SEQUENCE && cnt==0)         state_n  =   LAUNCH;  
                    else                                    state_n  =   state_c; 
                    
        LAUNCH:     if(state_c==LAUNCH)                     state_n  =   ON_MISSION; 
                    else					                		state_n  =   state_c;
                    
        ON_MISSION: if(state_c==ON_MISSION && !rst_n)       state_n  =   LAND;       //???怎么处理这种情况,只有复位信号可以改变的状态
                    else                                    state_n  =   state_c;
                    
        LAND:       if(state_c==LAND && is_landed)          state_n  =   HOLD;  
                    else                                    state_n  =   state_c;
                    
        default:                                            state_n  =   5'bx;  
    endcase
end

//输出为时序逻辑
always@(posedge clk or negedge rst_n)   begin
    if(!rst_n)                                      {launch_shuttle,land_shuttle,start_countdowns,start_trip_meter} <=  4'b0000;                
    else if(state_c==HOLD && all_system_go)         start_countdowns    <=  1;
    else if(state_c==LAUNCH)                        launch_shuttle      <=  1;
    else if(state_c==ON_MISSION && just_launched)   start_trip_meter    <=  1;     
    else if(state_c==LAND && is_landed)             land_shuttle        <=  1;
    else                                            {launch_shuttle,land_shuttle,start_countdowns,start_trip_meter} <=  4'bx;
end

endmodule
p182 13.3 4数据大小比较后排序(task使用)
/******************************p182 13.3 4数据大小比较后排序(task使用)********************************/
module  sort4(a,b,c,d,aout,bout,cout,dout);
parameter   t=3;
input       [t:0]   a,b,c,d;
output  reg [t:0]   aout,bout,cout,dout

task    sort2;
    inout   [t:0]   x,y;
    reg     [t:0]   tmp;
    begin
        if(x>y) 
            begin
                tmp=x;
                x=y;
                y=tmp;
            end
    end
endtask

always@(*)  begin:local             //必须要给begin-end块命名,因为定义了局部变量
reg         [t:0]   atmp,btmp,ctmp,dtmp;
    {atmp,btmp,ctmp,dtmp}   =   {a,b,c,d};
    sort2(atmp,ctmp);
    sort2(btmp,dtmp);
    sort2(atmp,btmp);
    sort2(ctmp,dtmp);
    sort2(btmp,ctmp);
    {aout,bout,cout,dout}   =   {atmp,btmp,ctmp,dtmp}
end

p180 13.4 锁存器误生成的示例
/******************************p180 13.4 锁存器误生成的示例********************************/
input   a,b,c,d;
output  e;

always@(a or b or c)    begin
    d=e | c;
    e=d&a&b&c;                  //d不在敏感表中,所以当d变化时,e不能立刻变化,要等a\b\c发生变化才能体现出d的变化,相当于d被锁存,即一个对a\b\c电平敏感的透明锁存器
end

endmodule
p182 13.2 计算器组合逻辑
/******************************p182 13.2 计算器组合逻辑********************************/
module  alu(out,opcode,a,b);

input   [7:0]   a,b;
output  reg [13:0]  out;
input   [4:0]   opcode;

parameter   plus    =   5'b00001,
            minus   =   5'b00010,
            band    =   5'b00100,
            bor     =   5'b01000,
            unegate =   5'b10000;

always@(opcode or a or b)   begin
    case(opcode)
        plus:   out=a+b;
        minus   out=a-b;
        band:   out=a&b;
        bor:    out=a|b;
        unegate:out= ~a;
        default:out=14'bx;
    endcase
end

endmodule
p182 13.3 4数据大小比较后排序(task使用)
/******************************p182 13.3 4数据大小比较后排序(task使用)********************************/
module  sort4(a,b,c,d,aout,bout,cout,dout);
parameter   t=3;
input       [t:0]   a,b,c,d;
output  reg [t:0]   aout,bout,cout,dout

task    sort2;
    inout   [t:0]   x,y;
    reg     [t:0]   tmp;
    begin
        if(x>y) 
            begin
                tmp=x;
                x=y;
                y=tmp;
            end
    end
endtask

always@(*)  begin:local             //必须要给begin-end块命名,因为定义了局部变量
reg         [t:0]   atmp,btmp,ctmp,dtmp;
    {atmp,btmp,ctmp,dtmp}   =   {a,b,c,d};
    sort2(atmp,ctmp);
    sort2(btmp,dtmp);
    sort2(atmp,btmp);
    sort2(ctmp,dtmp);
    sort2(btmp,ctmp);
    {aout,bout,cout,dout}   =   {atmp,btmp,ctmp,dtmp}
end
endmodule
p183 13.5 3-8译码器组合逻辑
/******************************p183 13.5 3-8译码器组合逻辑********************************/
module  38decoder(ain,bout);
input       [2:0]   ain;
output      [7:0]   bout;

assign  bout=1'b1<<ain;

endmodule
p183 13.6 8-3编码器组合逻辑
/******************************p183 13.6 8-3编码器组合逻辑********************************/
module  83encoder(on,out,in);
input       [7:0]   in;
output  reg [2:0]   out;
output  reg         on;

always@(in) begin:local
integer             i;
out=0;
on=1;
    for(i=0;i<8;i=i+1)  begin
        if(in[i])   begin
            out=i;
            on=0;
        end
    end
end

endmodule

/******************************p184 13.6.2 8-3编码器组合逻辑2********************************/
module  83encoder(on,out1,out2,out0,a,b,c,d,e,f,g,h);
input           a,b,c,d,e,f,g,h;
output          out0,out1,out2,on;
wire    [3:0]   outvec;    

assign  outvec  =   h? 4'b0111: g? 4'b0110: f? 4'b0101: e? 4'b0100: d? 4'b0011: c? 4'b0010: b? 4'b0001: a? 4'b0000: 4'b1000;

assign  on      =   outvec[3];
assign  out2    =   outvec[2];
assign  out1    =   outvec[1];
assign  out0    =   outvec[0];

endmodule
p186 13.9 三态门
/******************************p186 13.9 三态门********************************/
module  trit1(out,enable,in);
parameter   t=4;
input   [t:0]   in;
input           enable;
output  [t:0]   out;

assign  out = enable? in : t'bz;

endmodule
p186 13.10 三态双向驱动器
/******************************p186 13.10 三态双向驱动器********************************/
module  bidir(tri_inout,enable,out,in,b);
parameter   t=4;
inout   [t:0]   tri_inout;
input   [t:0]   in;
input           enable,b;
output  [t:0]   out;
assign  tri_inout = en? in : t'bz;
assign  out = tri_inout ^ b;

endmodule
p187 13.11 时钟正边沿触发器&时钟正电平敏感锁存器
/******************************p187 13.11 时钟正边沿触发器&时钟正电平敏感锁存器********************************/
module  dff(q,data,clk);
input   clk,data;
output  reg q;

always@(posedge clk)
    q<=data;
    
endmodule

module  latchpos(q,data,clk);
input   clk,data;
output  reg q;

assign q=(clk==1)?data:q;
    
endmodule

module  latchpos_reset_preset(q,data,clk,reset,preset);
input   clk,data,reset,preset;
output  reg q;

assign q=reset?0:(preset?1:(clk?data:q));
/*
always@(*)    begin
    if(reset)       q=0;
    else if(preset) q=1;
    else if(clk)    q=data;
    else            q=q;
end
*/    
endmodule
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值