Forum: FPGA, VHDL & Co. Umwandlung Verilog / VHDL, kann man das einfacher machen?


von Michael F. (mifi)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

: Bearbeitet durch Moderator
von Michael F. (mifi)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

: Bearbeitet durch Moderator
von Michael F. (mifi)


Lesenswert?

Ups, Danke.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.