Last active
November 11, 2021 04:56
-
-
Save ZakyHermawan/ac824f580b1ebfca2fe726324a6d54dc to your computer and use it in GitHub Desktop.
Operasi perkalian pada GF(128) dengan VHDL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- mpand and mplier is multiplicand and multiplier | |
-- modulus is modulus | |
-- product is the remainder | |
-- clk is clock | |
-- ds for D selector | |
-- reset is to go back to first state | |
-- ready mean that the value is product is the remainder of operation (final value) | |
-- only take the value when ready is true | |
-- note: the modulus is not yet validated as primitive polynomial (todo) | |
library IEEE; | |
use IEEE.STD_LOGIC_1164.ALL; | |
use IEEE.STD_LOGIC_ARITH.ALL; | |
use IEEE.STD_LOGIC_UNSIGNED.ALL; | |
-- Uncomment the following lines to use the declarations that are | |
-- provided for instantiating Xilinx primitive components. | |
--library UNISIM; | |
--use UNISIM.VComponents.all; | |
entity modmult is | |
Generic (MPWID: integer := 8); | |
Port ( mpand : in std_logic_vector(MPWID-1 downto 0); | |
mplier : in std_logic_vector(MPWID-1 downto 0); | |
modulus : in std_logic_vector(MPWID-1 downto 0); | |
product : out std_logic_vector(MPWID-1 downto 0); | |
clk : in std_logic; | |
ds : in std_logic; | |
reset : in std_logic; | |
ready : out std_logic); | |
end modmult; | |
architecture modmult1 of modmult is | |
signal mpreg: std_logic_vector(MPWID-1 downto 0); | |
signal mcreg, mcreg1, mcreg2: std_logic_vector(MPWID+1 downto 0); | |
signal modreg1, modreg2: std_logic_vector(MPWID+1 downto 0); | |
signal prodreg, prodreg1, prodreg2, prodreg3, prodreg4: std_logic_vector(MPWID+1 downto 0); | |
--signal count: integer; | |
signal modstate: std_logic_vector(1 downto 0); | |
signal first: std_logic; | |
begin | |
-- final result... | |
product <= prodreg4(MPWID-1 downto 0); | |
-- add shifted value if place bit is '1', copy original if place bit is '0' | |
with mpreg(0) select | |
prodreg1 <= prodreg + mcreg when '1', | |
prodreg when others; | |
-- subtract modulus and subtract modulus * 2. | |
prodreg2 <= prodreg1 - modreg1; | |
prodreg3 <= prodreg1 - modreg2; | |
-- negative results mean that we subtracted too much... | |
modstate <= prodreg3(mpwid+1) & prodreg2(mpwid+1); | |
-- select the correct modular result and copy it.... | |
with modstate select | |
prodreg4 <= prodreg1 when "11", | |
prodreg2 when "10", | |
prodreg3 when others; | |
-- meanwhile, subtract the modulus from the shifted multiplicand... | |
mcreg1 <= mcreg - modreg1; | |
-- select the correct modular value and copy it. | |
with mcreg1(MPWID) select | |
mcreg2 <= mcreg when '1', | |
mcreg1 when others; | |
ready <= first; | |
combine: process (clk, first, ds, mpreg, reset) is | |
begin | |
if reset = '1' then | |
first <= '1'; | |
elsif rising_edge(clk) then | |
if first = '1' then | |
-- First time through, set up registers to start multiplication procedure | |
-- Input values are sampled only once | |
if ds = '1' then | |
mpreg <= mplier; | |
mcreg <= "00" & mpand; | |
modreg1 <= "00" & modulus; | |
modreg2 <= '0' & modulus & '0'; | |
prodreg <= (others => '0'); | |
first <= '0'; | |
end if; | |
else | |
-- when all bits have been shifted out of the multiplicand, operation is over | |
-- Note: this leads to at least one waste cycle per multiplication | |
if mpreg = 0 then | |
first <= '1'; | |
else | |
-- shift the multiplicand left one bit | |
mcreg <= mcreg2(MPWID downto 0) & '0'; | |
-- shift the multiplier right one bit | |
mpreg <= '0' & mpreg(MPWID-1 downto 1); | |
-- copy intermediate product | |
prodreg <= prodreg4; | |
end if; | |
end if; | |
end if; | |
end process combine; | |
end modmult1; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment