Python:VHDL代码生成器的代码
我正在用VHDL语言制作一个ROM,我用的是在http://www.edaboard.com/thread38052.html上找到的这个模板:
library ieee;
use ieee.std_logic_1164.all;
entity ROM is
port ( address : in std_logic_vector(3 downto 0);
data : out std_logic_vector(7 downto 0) );
end entity ROM;
architecture behavioral of ROM is
type mem is array ( 0 to 2**4 - 1) of std_logic_vector(7 downto 0);
constant my_Rom : mem := (
0 => "00000000",
1 => "00000001",
2 => "00000010",
3 => "00000011",
4 => "00000100",
5 => "11110000",
6 => "11110000",
7 => "11110000",
8 => "11110000",
9 => "11110000",
10 => "11110000",
11 => "11110000",
12 => "11110000",
13 => "11110000",
14 => "11110000",
15 => "11110000");
begin
process (address)
begin
case address is
when "0000" => data <= my_rom(0);
when "0001" => data <= my_rom(1);
when "0010" => data <= my_rom(2);
when "0011" => data <= my_rom(3);
when "0100" => data <= my_rom(4);
when "0101" => data <= my_rom(5);
when "0110" => data <= my_rom(6);
when "0111" => data <= my_rom(7);
when "1000" => data <= my_rom(8);
when "1001" => data <= my_rom(9);
when "1010" => data <= my_rom(10);
when "1011" => data <= my_rom(11);
when "1100" => data <= my_rom(12);
when "1101" => data <= my_rom(13);
when "1110" => data <= my_rom(14);
when "1111" => data <= my_rom(15);
when others => data <= "00000000";
end case;
end process;
end architecture behavioral;
问题是我想在我的ROM里放入2000个值。所以我在想怎么用Python来实现这个:
想象一下,你在一个.txt文件里有这样的数据格式:
0 45
1 56
2 78
3 98
程序会对这些数据进行这样的处理:
0 => "00101101"
1 => "00111000"
2 => "01001110"
3 => "01100010"
这些值“00101101”、“00111000”、“01001110”、“01100010”分别代表了45、56、78和89的二进制表示。所以,你明白我的意思了……
还有一个小细节,就是需要指定表示所需的位数:如果不指定,你可能会得到这样的结果:
0 => "101101"
1 => "111000"
2 => "1001110"
3 => "1100010"
非常感谢所有提供代码帮助的人!
4 个回答
这里还有一种方法,就是在MyHDL中使用toVHDL转换器。你可以用任意的Python表达式来初始化一个元组。
这是MyHDL的描述:
from myhdl import *
def VhdlRomGen(addr, data):
# Create the ROM container
rom = [Signal(intbv(0)[8:]) for ii in range(2**4)]
# Initialize ROM, any value, any complex python can
# be in this initialization code.
for ii in xrange(len(rom)):
rom[ii] = ii
rom = tuple(rom)
@always_comb
def rtl_rom():
data.next = rom[int(addr)]
return rtl_rom
if __name__ == "__main__":
addr = Signal(intbv(0)[4:])
data = Signal(intbv(0)[8:])
toVHDL(VhdlRomGen, addr, data)
这是转换后的VHDL代码:
-- Generated by MyHDL 0.7
-- Date: Sat May 21 15:39:27 2011
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_07.all;
entity VhdlRomGen is
port (
addr: in unsigned(3 downto 0);
data: out unsigned(7 downto 0)
);
end entity VhdlRomGen;
architecture MyHDL of VhdlRomGen is
begin
VHDLROMGEN_RTL_ROM: process (addr) is
begin
case to_integer(addr) is
when 0 => data <= "00000000";
when 1 => data <= "00000001";
when 2 => data <= "00000010";
when 3 => data <= "00000011";
when 4 => data <= "00000100";
when 5 => data <= "00000101";
when 6 => data <= "00000110";
when 7 => data <= "00000111";
when 8 => data <= "00001000";
when 9 => data <= "00001001";
when 10 => data <= "00001010";
when 11 => data <= "00001011";
when 12 => data <= "00001100";
when 13 => data <= "00001101";
when 14 => data <= "00001110";
when others => data <= "00001111";
end case;
end process VHDLROMGEN_RTL_ROM;
end architecture MyHDL;
作为其他答案的一个替代方案,你可以让你的ROM存储natural
或integer
(根据需要选择)。这样你的常量可以写成以下形式:
0 => 45,
1 => 56, ...
等等。
如果你已经有了所有的值,你可以直接把它们放在一个大的用逗号分隔的序列中,而不需要进行n =>
的位置映射。
(45, 56, 78, 98,....)
另外,如果你把地址输入设置为数字类型(可以选择unsigned
或natural
),那么你可以简化地址解码,变成:
data <= my_rom(address);
或者
data <= my_rom(to_integer(address));
当然可以!请看下面的内容:
在编程中,有时候我们需要让程序做一些特定的事情,比如在某个条件下执行某段代码。这个过程就像是在给程序下指令,让它知道什么时候该做什么。
有些时候,我们会用到“条件语句”,这就像是在问程序:“如果这个条件成立,你会怎么做?”如果条件成立,程序就会执行你指定的代码;如果不成立,程序就会跳过这段代码,继续执行后面的内容。
举个例子,假设你在写一个程序,想要检查用户输入的密码是否正确。你可以设置一个条件语句,告诉程序:“如果用户输入的密码和我设定的密码相同,就显示‘密码正确’,否则显示‘密码错误’。”这样,程序就能根据用户的输入来决定显示什么信息。
希望这个解释能帮助你更好地理解条件语句的用法!
for line in open('your_file.txt'):
s = line.strip().split(" ") # two spaces are for split
p = '{} => "{:0{min_bits}b}"'.format(s[0], int(s[1]), min_bits=10)
print p