Umwandlung Verilog / VHDL, kann man das einfacher machen?

OP #4212945
Lesenswert?

Hallo zusammen,

ich versuche gerade den Source von einer MIPS CPU von Verilog nach VHDL 
umzusetzen. Meine Umsetzung scheint zu funktionieren, da die CPU
noch läuft :o)

Aber kann man die Umsetzung nach VHDL noch einfacher machen?

Hier nun der Verilog Source:
1
module RegisterFile(
2
    input  clock,
3
    input  reset,
4
    input  [4:0]  ReadReg1, ReadReg2, WriteReg,
5
    input  [31:0] WriteData,
6
    input  RegWrite,
7
    output [31:0] ReadData1, ReadData2
8
    );
9

10
    // Register file of 32 32-bit registers. Register 0 is hardwired to 0s
11
    reg [31:0] registers [1:31];
12

13
    // Initialize all to zero
14
    integer i;
15
    initial begin
16
        for (i=1; i<32; i=i+1) begin
17
            registers[i] <= 0;
18
        end
19
    end
20

21
    // Sequential (clocked) write.
22
    // 'WriteReg' is the register index to write. 'RegWrite' is the command.
23
    always @(posedge clock) begin
24
        if (reset) begin
25
            for (i=1; i<32; i=i+1) begin
26
                registers[i] <= 0;
27
            end
28
        end
29
        else begin
30
            if (WriteReg != 0)
31
                registers[WriteReg] <= (RegWrite) ? WriteData : registers[WriteReg];
32
        end
33
    end
34

35
    // Combinatorial Read. Register 0 is all 0s.
36
    assign ReadData1 = (ReadReg1 == 0) ? 32'h00000000 : registers[ReadReg1];
37
    assign ReadData2 = (ReadReg2 == 0) ? 32'h00000000 : registers[ReadReg2];
38

39
endmodule

Und das ist meine Übersetzung:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5
entity RegisterFile is
6
   port (
7
      clock     : in  std_logic := '0';
8
      reset     : in  std_logic := '0';
9
      ReadReg1  : in  std_logic_vector(4 downto 0) := (others => '0');
10
      ReadReg2  : in  std_logic_vector(4 downto 0) := (others => '0');
11
      WriteReg  : in  std_logic_vector(4 downto 0) := (others => '0');
12
      WriteData : in  std_logic_vector(31 downto 0) := (others => '0');
13
      RegWrite  : in  std_logic := '0';
14
      ReadData1 : out std_logic_vector(31 downto 0);
15
      ReadData2 : out std_logic_vector(31 downto 0)
16
   );
17
end entity RegisterFile;
18

19
architecture syn of RegisterFile is
20

21
   type reg_t is array (0 to 31) of std_logic_vector(31 downto 0); 
22
   signal registers : reg_t := (others => (others => '0')); 
23
   
24
begin
25

26
   -- Sequential (clocked) write.
27
   -- 'WriteReg' is the register index to write. 'RegWrite' is the command.
28
   process (clock)
29
   begin
30
      if (rising_edge(clock)) then
31
         if (reset = '1') then
32
            for i in 1 to 31 loop
33
               registers(i) <= (others =>'0');
34
            end loop; 
35
         else
36
            if (WriteReg /= "00000") then
37
               if (RegWrite = '1') then
38
                  registers(to_integer(unsigned(WriteReg))) <= WriteData; 
39
               else
40
                  registers(to_integer(unsigned(WriteReg))) <= registers(to_integer(unsigned(WriteReg)));
41
               end if;
42
            end if;
43
         end if;   
44
      end if; 
45
   end process;
46
   
47
   -- Combinatorial Read. Register 0 is all 0s.
48
   ReadData1 <= x"00000000" when (ReadReg1 = "00000") else registers(to_integer(unsigned(ReadReg1)));
49
   ReadData2 <= x"00000000" when (ReadReg2 = "00000") else registers(to_integer(unsigned(ReadReg2)));
50

51
end architecture syn;

Gibt es hier noch eine bessere Lösung als:

to_integer(unsigned(WriteReg))

Gruß,
Michael
Moderator (Firma: Titel) Persönliche Seite #4213025
Lesenswert?

Du könntest mit extra Integer-Signalen arbeiten, denen nebenläufig diese 
Adresse einmal zugewiesen wird...
Aber das bringt hier nicht arg viel mehr Übersicht.

Michael F. schrieb:
> registers(to_integer(unsigned(WriteReg))) <=
> registers(to_integer(unsigned(WriteReg)));
Das ist unnötig, weil es nichts ändert. Insofern ist hier die Verilog 
Version etwas überzogen...
OP #4213035
Lesenswert?

Hallo Lothar,

Danke für die Info. Was mich im Moment etwas wundert ist das der
Verbrauch an Registern beim meiner VHDL Umsetzung etwas gestiegen
ist im Vergleich zu der Verilog Lösung. Mal schauen was am Ende bei
rauskommt wenn ich fertig bin.

Ich habe hier noch einige Konstrukte wo ich noch nicht so richtig
weiß wie ich das in VHDL machen soll...

Gruß,
Michael
Moderator (Firma: Titel) Persönliche Seite #4213568
Lesenswert?

Michael F. schrieb:
> der Verbrauch an Registern ... etwas gestiegen
Uuups natürlich, übersehen: die Umsetzung hat noch einen grundlegenden 
Fehler, und deshalb "braucht" die Synthese 32 Register mehr (die im 
späteren Verlauf allerdings wegoptimiert werden würden, weil sie nicht 
verwendet werden).
Denn da steht:
1
type reg_t is array (0 to 31) of ...    // also 32 * 32 Bit
In Verilog steht da:
1
... registers [1:31];                   // also 31 * 32 Bit
Und das ergibt dann natürlich im weiteren Verlauf Probleme mit dieser 
Abfrage:
1
   if (WriteReg /= "00000") then     // das Register 0 wird nie verwendet

Also mach es einfach so wie in der Verilog Beschreibung:
1
   type reg_t is array (1 to 31) of std_logic_vector(31 downto 0);

Dann ergibt sich:
1
Macro Statistics
2
# Registers                                            : 31
3
 32-bit register                                       : 31
4

5
# Registers                                            : 992
6
 Flip-Flops                                            : 992
Und das passt exakt...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren