当前位置:   article > 正文

(三)vhdl如何转换转换verilog?(人肉翻译—保姆教学版)_vhdl中conv_integer这一句变成verilog语句怎么变

vhdl中conv_integer这一句变成verilog语句怎么变

一、前言

        几个星期没有更新了,最近一直忙,现在能抽点时间继续补充了。其次我就是想吐槽一下这个csdn自带的文章编辑,已经习惯了撤销是ctrl+z,谁知道这里是从头到尾都撤销了,相当于删除了所有,已经两次了,想要恢复已经来不及了。心态直接炸了,没办法,再重新写吧,害!

二,进入转换

        1,多个三目运算用法的转换

VHDL中单个三目运算还是能看来出来的,但是多个在一起的用法可能对于新手来说不是很友好,所以在这里遇到了就顺便提及一下,直接上代码

A  <= '0' when (B  = '0') else '1' when (B = '1') else '0';

其实理解了它想表达的意思,转换过来就不是很难,大体可以这样理解:当B  = '0' 时,A  <= '0' ;当B  = '1' 时,A  <= '1';else A  <= '0',(反正我是这样理解的,有错误或者有异议的可以在评论区指点一下)转换后如下

   assign A = ((B == 1'b0)) ? 1'b0 : ((B == 1'b1)) ? 1'b1 : 1'b0;

注意点就是转换过来时是assign赋值语句。

当然,为其他值的情况也一样,如下

A <= C  when (B = '0') else D  when (B  = '1') else C;  
   assign A = ((B == 1'b0)) ? C: ((B == 1'b1)) ? D : C;

2,process和always

process相当于verilog中的always语句,直接转换就行,要注意的是上下沿的变化。

  1. process (clk,rst_n) begin
  2. if (rst_n='1') then
  3. data <= '0';
  4. elsif (clk'Event and clk='1') then
  5. if (data_d1 = '0' and data_d2 = '1') then
  6. data <= '1';
  7. else
  8. data <= '0';
  9. end if;
  10. end if;
  11. end process;

上面这里process后面括号里面都为上升沿所以转换过来就是always@(posedge clk or posedge rst_n), 之后的(clk'Event and clk='1') then的意思可以理解为clk'event是指信号clk是否发生跳变,若发生了则返回ture,否则为假,clk=‘1’是跳变后clk为高电平。合起来就是当clk信号的上升沿则.... 都说VHDL严谨,从这里就可以看得出,但转换成verilog后这句基本是省略掉的,if条件语句变化不大,这里就不做过多的赘述,所以转换后的如下

  1. always @(posedge clk or posedge rst_n)begin
  2. if (rst_n== 1'b1)
  3. data <= 1'b0;
  4. else begin
  5. if (data_d1 == 1'b0 && data_d2 == 1'b1)
  6. data <= 1'b1;
  7. else
  8. data <= 1'b0;
  9. end
  10. end

 转换过来后就比较清晰明了了,VHDL注重严谨,所以看起来就很繁琐,verilog只要逻辑语法正确,很好掌握的,对初学者也很友好。

        3、case语句

在always语句也有经常会遇到多路条件分支的形式,一般用的就是case语句

  1. process (sclk,rst_n) begin
  2. if (rst_n='1') then
  3. data1 <= (others => '0');
  4. data2 <= (others => '0');
  5. data3 <= (others => '0');
  6. elsif (clk'event and clk='1') then
  7. case (sel) is
  8. when "00" =>
  9. data1 <= channel0;
  10. data2 <= channel0;
  11. data3 <= channel0;
  12. when "01" =>
  13. data1 <= channel1;
  14. data2 <= channel1;
  15. data3 <= channel1;
  16. when "10" =>
  17. data1 <= channel2;
  18. data2 <= channel2;
  19. data3 <= channel2;
  20. when "11" =>
  21. data1 <= channel3;
  22. data2 <= channel3;
  23. data3 <= channel3;
  24. when others =>
  25. data1 <= (others => '0');
  26. data2 <= (others => '0');
  27. data3 <= (others => '0');
  28. end case;

这里data1   <= (others => '0');它的意思是将data1的所有位都设为‘0’,前面也有提及到,这里就再补充一下另外一种写法,倘若data1定义为8位的数据,则转换成verilog后为:data1 <=    {8{1'b0}};当然也可以用之前说过的写法,看个人喜好来理解。最终整个语句转换后如下

  1. always @(posedge clk or posedge rst_n)
  2. if (rst_n== 1'b1)
  3. begin
  4. data1 <= {8{1'b0}};
  5. data2 <= {8{1'b0}};
  6. data3 <= {8{1'b0}};
  7. end
  8. else
  9. case (sel)
  10. 2'b00 :
  11. begin
  12. data1 <= channel0;
  13. data2 <= channel0;
  14. data3 <= channel0;
  15. end
  16. 2'b01 :
  17. begin
  18. data1 <= channel1;
  19. data2 <= channel1;
  20. data3 <= channel1;
  21. end
  22. 2'b10 :
  23. begin
  24. data1 <= channel2;
  25. data2 <= channel2;
  26. data3 <= channel2;
  27. end
  28. 2'b11 :
  29. begin
  30. data1 <= channel3;
  31. data2 <= channel3;
  32. data3 <= channel3;
  33. end
  34. default :
  35. begin
  36. data1 <= {8{1'b0}};
  37. data2 <= {8{1'b0}};
  38. data3 <= {8{1'b0}};
  39. end
  40. endcase

另一种常见的用法

  1. process (clk,rst_n) begin
  2. if (rst_n='1') then
  3. data <= (others => '0'); //16位的数据
  4. elsif (clk'Event and clk='1') then
  5. case sel (3 downto 0) is
  6. when x"0" => data <= x"0" & channel0;
  7. when x"1" => data <= x"0" & channel1;
  8. when x"2" => data <= x"0" & channel2;
  9. when x"3" => data <= x"0" & channel3;
  10. when x"4" => data <= x"0" & channel4;
  11. when x"5" => data <= x"0" & channel5;
  12. when others => data <= (others => '0');
  13. end case;
  14. end if;
  15. end process;

转换后

  1. always @(posedge clk or posedge rst_n)
  2. if (rst_n == 1'b1)
  3. data <= {16{1'b0}};
  4. else
  5. case (sel[3:0])
  6. 4'h0 :
  7. data <= {4'h0, channel0};
  8. 4'h1 :
  9. data <= {4'h0, channel1};
  10. 4'h2 :
  11. data <= {4'h0, channel2};
  12. 4'h3 :
  13. data <= {4'h0, channel3};
  14. 4'h4 :
  15. data <= {4'h0, channel4};
  16. 4'h5 :
  17. data <= {4'h0, channel5};
  18. default :
  19. data <= {16{1'b0}};
  20. endcase

4、VHDL数据类型(Data Types)

VHDL中共有4类类型:标量类型、复合类型、访问类型、文件类型。你可以基于上述类型的基础上自定义自己的类型,或者使用subtype关键字来约束已存在的类型。感兴趣的可以去了解一下,这里用到的是标量类型中的枚举类型。

枚举类型:枚举类型是一组具有明确值的集合。枚举中的值是一个命名项或者一个字符。              语法(Syntax)

type 枚举名 is ( 枚举元素, 枚举元素, ... );
type new_name is ( type_element, type_element, ... );

这里用来作为状态机的定义,很简单的用法

  1. type FSM is (
  2. IDLE ,
  3. WRITE_1 ,
  4. READ_1 ,
  5. WRITE_2 ,
  6. READ_2 ,
  7. READ_WAIT
  8. );

转换后就是这样

  1. parameter [2:0] FSM_IDLE = 3'd0,
  2. FSM_WRITE_1 = 3'd1,
  3. FSM_READ_1 = 3'd2,
  4. FSM_WRITE_2 = 3'd3,
  5. FSM_READ_2 = 3'd4,
  6. FSM_READ_WAIT = 3'd5;

这章就到这里吧,目前遇到的几个常用的语法也就这么多了,这只是字面上的转换,具体还得读懂代码会用代码,那样的话遇到或者用到就比较方便了,最后还是那句话,有错误或者异议的欢迎各位大佬在评论区留言探讨。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号