集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1646|回复: 2

case语法和task语法

[复制链接]
zxopenluyutong 发表于 2021-5-22 09:14:05 | 显示全部楼层 |阅读模式
module ex_case(
            input  wire           rst_n,
            input  wire           sclk,
            output reg            o_dv,//使能标志信号,标志数据有效
            output reg     [7:0]  o_data,
            //用于数据输入
            input  wire    [9:0]  i_data,
            input  wire    [7:0]  i_addr
);

reg  [2:0] cnt_7;//计数器
//不同功能的寄存器分开always块来写,这样可维护性强,可读性强
always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)   
                        cnt_7<=3'd0;
                else
                        cnt_7<=cnt_7 + 1'b1;

always @(posedge sclk or negedge rst_n)//case语句只能在always块里面,case语句是并行语句,没有先后
                if(rst_n == 1'b0)
                begin
                        o_data<=8'd0;
                        o_dv<=1'b0;
                end
                else begin
                            case(cnt_7)
                                    3'd0:begin
                                                    o_data<=3'd7;//当cnt_7等于3'd0执行此条语句,
                                                    o_dv<=1'b1;//reg的概念:上升沿前面的低电平把数据加载到D端,当上升沿来临的时候就把D端的数据呈现在Q端
                                             end
                                    3'd1:begin
                                                    o_data<=3'd0;//case语句相当于一个译码器,对应一个真值表(综合时生成LUT)
                                                    o_dv<=1'b0;
                                             end
                                    3'd2:begin
                                                    o_data<=3'd5;
                                                    o_dv<=1'b1;
                                             end
                                    default:begin
                                                        o_data<=3'd0;
                                                        o_dv<=1'b0;
                                                    end
                            endcase
                end

//下列是组合逻辑实现
//消除锁存器:
//1.把敏感列表写全,case条件;赋值语句右边的变量;
//2.所有条件分支写全
//always @(cnt_7)//敏感列表是变量的时候是组合逻辑。是电平触发。敏感列表必须要完整,否则生成锁存器(只有电平触发的时候才有可能生成锁存器)。锁存器延迟的时间不固定还是电平触发,导致此路径不能参与到时序分析里边
//                          case(cnt_7)
//                                  3'd0:begin
//                                                  o_data<=3'd7;//当cnt_7等于3'd0执行此条语句
//                                                  o_dv<=1'b1;
//                                           end
//                                  3'd1:begin
//                                                  o_data<=3'd0;//case语句相当于一个译码器,对应一个真值表(综合时生成LUT(查找表就是把一些真值表存在里面),真值表的条件当地址,真值表的输出结果作为输出)
//                                                  o_dv<=1'b0;
//                                           end
//                                  3'd2:begin
//                                                  o_data<=3'd5;
//                                                  o_dv<=1'b1;
//                                           end
//                                  default:begin//可以直接加一个“;”结束
//                                                      o_data<=3'd0;
//                                                      0_dv<=1'b0;
//                                                  end
//                          endcase
endmodule
/*
wire和reg的具体区别
在RTL图里就可以看到:
wire就是一根线
reg就是一个D触发器,是一个硬件的元件(也可以理解为一个模块)
FPGA的基本单元是LE,一个LE里面会有寄存器
*/12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
`timescale  1ns /1ns

module tb_ex_case;
reg   sclk,rst_n;
wire  [7:0]  data;
wire         dv;
reg   [7:0]  i_addr;
reg   [9:0]  i_data;

initial begin
                sclk  = 0;
                rst_n = 0;
                #200
                rst_n = 1;

end

initial begin
            i_data=0;
            i_addr=0;
            #500
            send_data(255);
end

always #10 sclk <=~sclk;//周期20ns的时钟

ex_case ex_case_inst(
            .rst_n         (rst_n),
            .sclk          (sclk),
            .o_dv          (dv),
            .o_data        (data),
            //用于数据输入
            .i_data        (i_data),
            .i_addr        (i_addr)
);

task send_data(len);//任务名字和长度,任务的声明,类似C语言
       integer len,i;//变量声明区
       begin//必须加begin和end
                for(i=0;i<len;i=i+1)//循环语句
                begin
                        @(posedge sclk);//for循环的时候一定要按照节拍来工作。如果注视掉本行,在波形图上i_data和i_addr都为零不动了。因为瞬间溢出成0
                        i_addr<=i[7:0];//可以用阻塞赋值也可以用非阻塞赋值。阻塞赋值就是直接赋过去,非阻塞赋值会延时一拍。
                        i_data<=i[7:0];//截取低8位
                        //用case语句产生一个协议,当地址为0时,i_data=0xff;
                        //当地址为1时,i_data=0x55;
                        //当地址为2时,i_data=0x00;
                        //其他地址全部保留赋值为0xff;
                end
                i_addr<=0;
            i_data<=0;
       end  
endtask
endmodule

/*
如果去描述一个ram,地址不要用case语句来描述,要用存储器变量,存储器变量使用reg来声明的。
单片机或arm这一类的芯片要和FPGA通信的时候,会有一个并行总线,并行总线给过来地址,可以用case来做
就相当于arm芯片来读取FPGA的一些寄存器的时候就可以用case语句来做
zhangyukun 发表于 2021-5-22 16:53:08 | 显示全部楼层
case语法和task语法
lihongkun16 发表于 2021-5-23 22:25:54 | 显示全部楼层
case语法和task语法
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-28 23:55 , Processed in 0.057668 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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