Python: код для генератора кода VHDL - PullRequest
4 голосов
/ 11 февраля 2011

Я пытаюсь сделать ПЗУ на языке VHDL, я использую этот шаблон, который нашел на 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;

Ну, проблема в том, что я хочу вставить в свойЗначения ПЗУ 2000Поэтому мне было интересно, как сделать следующее с помощью python:

Представьте, что у вас есть в файле .txt эти данные в следующем формате:

0  45
1  56
2  78
3  98

Так что программа будет делать это сdata:

0 => "00101101"
1 => "00111000"
2 => "01001110"
3 => "01100010"

Эти значения "00101101", "00111000", "01001110", "01100010" являются соответствующими значениями для двоичного представления 45,56,78 y 89. Итак, вы получитеидея ...

Есть небольшая деталь, необходимо указать количество бит для представления: Если вы не можете получить это:

0 => "101101"
1 => "111000"
2 => "1001110"
3 => "1100010"

СпасибоВы так много для всех возможных кусков кода, чтобы сделать эту программу

Ответы [ 4 ]

5 голосов
/ 22 мая 2011

Вот еще один метод; используя конвертер toVHDL в MyHDL. Вы можете использовать произвольные выражения 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;
5 голосов
/ 11 февраля 2011

В качестве альтернативы другим ответам сделайте в вашем ПЗУ хранилище natural с или integer с (в зависимости от ситуации).Тогда ваша константа может иметь вид:

0 => 45,
1 => 56, ...

и т. Д.

Если у вас уже есть все значения, вы можете просто поместить их все в большую запятуюряд разделителей без выполнения позиционного сопоставления n =>.

(45, 56, 78, 98,....)

Кроме того, если вы вводите свой адрес числовым типом (либо unsigned, либо natural, как вам удобнее), вы можете упростить декодирование адреса.просто

data <= my_rom(address);

или

data <= my_rom(to_integer(address));
3 голосов
/ 11 февраля 2011
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
2 голосов
/ 11 февраля 2011

Попробуйте это:

bit_count = 8
format_template = '{{0}} => "{{1:0{0}b}}"'.format(bit_count)
with open(r"input_file.txt") as input_file:
    for line in input_file:
        data = map(int, line.split())
        print format_template.format(*data)
...