Ich verfolge den Kurs From NAND to Tetris , aber anstatt die Software des Autors zu verwenden, versuche ich, direkt ein Spartan 6 FPGA zu programmieren . Ich löse jetzt die ALU-Übung und habe am Ende den folgenden Code geschrieben ( Haftungsausschluss: Ich habe gestern angefangen, VHDL zu lernen):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity alu is
Port (x : in STD_LOGIC_VECTOR(15 downto 0);
y : in STD_LOGIC_VECTOR(15 downto 0);
zx : in STD_LOGIC;
nx : in STD_LOGIC;
zy : in STD_LOGIC;
ny : in STD_LOGIC;
f : in STD_LOGIC;
no : in STD_LOGIC;
output : out STD_LOGIC_VECTOR(15 downto 0);
zr : out STD_LOGIC;
ng : out STD_LOGIC);
constant zeros: STD_LOGIC_VECTOR(15 downto 0) := "0000000000000000";
end alu;
architecture Behavioral of alu is
begin
op: process(x, y, zx, nx, zy, ny, f, no)
variable px: STD_LOGIC_VECTOR(15 downto 0);
variable py: STD_LOGIC_VECTOR(15 downto 0);
variable po: STD_LOGIC_VECTOR(15 downto 0);
begin
px := x;
py := y;
px := zeros when (zx = '1');
px := not(px) when (nx = '1');
py := zeros when (zy = '1');
py := not(py) when (ny = '1');
if (f = '1') then
po := (px + py);
else
po := (px AND py);
end if;
po := not(po) when (no = '1');
output <= po;
if (po = zeros) then
zr <= '1';
else
zr <= '0';
end if;
ng <= po(0);
end process;
end Behavioral;
Ich frage mich jetzt, ob es einen einfacheren Weg gibt, dasselbe zu erreichen, wenn man bedenkt:
(VHDL) Gute Praktiken;
Es ist viel einfacher, das Timing von Besprechungen zu planen, wenn Sie jede Entität synchron machen - geben Sie ihr eine Uhr (und setzen Sie sie gegebenenfalls zurück) und schreiben Sie einen getakteten Prozess. Sie müssen sich dann auch nicht darum kümmern, Sensitivitätslisten aktuell zu halten.
Beachten Sie Folgendes:
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Verwenden Sie das nicht - obwohl es sich besser benimmt als std_logic_arith . Verwenden Sie ieee.numeric_std.all;
stattdessen und verwenden Sie dann die entsprechenden Typen für Ihre Vektoren.
Verwendung von Variablen - das ist ein gutes Zeichen in meinem Buch. Hält lokale Dinge sehr lokal.
Sie könnten Ihre Variablen automatisch skalieren:
variable px : std_logic_vector(x'range);
und Ihre Konstante (die Sie in die Architektur verschieben könnten, was konventioneller wäre):
constant zeros: STD_LOGIC_VECTOR(x'range) := (others => '0');
(VHDL) Codegröße
Ich bin mir nicht sicher, ob Sie so viel Code speichern könnten, ohne die Lesbarkeit zu verlieren
Verwenden Sie so wenig sequentielle Logik wie möglich;
Warum? Flipflops sind in FPGAs fast kostenlos. Mir gehen fast immer zuerst die LUTs aus.
Synthesegröße
Es kommt nicht oft vor, dass der Code den größten Einfluss auf die Synthesegröße hat. Es sind Dinge auf höherer Ebene wie parallel (viel Logik) vs. sequentiell (ein wenig Logik wiederum - aber vergessen Sie nicht, dass die Zustandsmaschine, die sie steuert, ein Overhead sein kann).