Skip to content

Instantly share code, notes, and snippets.

@mkatsimpris
Created January 20, 2016 13:41
Show Gist options
  • Save mkatsimpris/cd53a0d66a39b7770ee3 to your computer and use it in GitHub Desktop.
Save mkatsimpris/cd53a0d66a39b7770ee3 to your computer and use it in GitHub Desktop.
from myhdl import *
def mul(ina,inb,out1,clk,reset,width=8):
ina_reg,inb_reg=[intbv(0,-2**width,2**(width-1)) for i in range(2)]
out_reg=intbv(0,-2**(2*width),2**(2*width-1))
@always_seq(clk.posedge, reset=reset)
def logic():
ina_reg=ina
inb_reg=inb
out_reg=intbv(ina_reg*inb_reg,-2**(2*width),2**(2*width-1))
out1.next=out_reg
return logic
width=8
ina,inb=[Signal(intbv(0,-2**width,2**(width-1))) for i in range(2)]
out1=Signal(intbv(0,-2**(2*width),2**(2*width-1)))
clk = Signal(bool(0))
reset = ResetSignal(1, active=1, async=True)
toVHDL(mul,ina,inb,out1,clk,reset)
-- File: mul.vhd
-- Generated by MyHDL 0.9.0
-- Date: Wed Jan 20 15:39:39 2016
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_090.all;
entity mul is
port (
ina: in signed (8 downto 0);
inb: in signed (8 downto 0);
out1: out signed (16 downto 0);
clk: in std_logic;
reset: in std_logic
);
end entity mul;
architecture MyHDL of mul is
constant width: integer := 8;
begin
MUL_LOGIC: process (clk, reset) is
variable inb_reg: signed(8 downto 0);
variable out_reg: signed(16 downto 0);
variable ina_reg: signed(8 downto 0);
begin
if (reset = '1') then
out1 <= to_signed(0, 17);
elsif rising_edge(clk) then
ina_reg := ina;
inb_reg := inb;
out_reg := to_signed((ina_reg * inb_reg), 17);
out1 <= out_reg;
end if;
end process MUL_LOGIC;
end architecture MyHDL;
@josyb
Copy link

josyb commented Jan 20, 2016

Use Signal(intbv()):
I also changed the widths in the intbv() instantiations; if you specify 8 'negative' bits and 8 'positive' bits your result will have 18 bits in total.

from myhdl import *



def mul(ina,inb,out1,clk,reset,width=8):

    ina_reg, inb_reg = [Signal(intbv(0, -2**width, 2**(width))) for _ in range(2)]
    @always_seq(clk.posedge, reset=reset)
    def logic():
        ina_reg.next = ina
        inb_reg.next = inb
        out1.next = ina_reg * inb_reg

    return logic

width = 8
ina, inb = [Signal(intbv(0, -2**width, 2**(width))) for _ in range(2)]
out1 = Signal(intbv(0, -2**(2*width+1), 2**(2*width+1)))
clk = Signal(bool(0))
reset = ResetSignal(1, active=1, async=True)
toVHDL(mul, ina, inb, out1, clk, reset)
-- File: mul.vhd
-- Generated by MyHDL 1.0dev
-- Date: Wed Jan 20 15:04:45 2016


library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_10.all;

entity mul is
    port (
        ina   : in  signed(8 downto 0);
        inb   : in  signed(8 downto 0);
        out1  : out signed(17 downto 0);
        clk   : in  std_logic;
        reset : in  std_logic
        );
end entity mul;


architecture MyHDL of mul is

    signal ina_reg : signed(8 downto 0);
    signal inb_reg : signed(8 downto 0);

begin

    logic: process (clk, reset) is
        begin
            if (reset = '1') then
                inb_reg <= to_signed(0, 9);
                ina_reg <= to_signed(0, 9);
                out1 <= to_signed(0, 18);
            elsif rising_edge(clk) then
                ina_reg <= ina;
                inb_reg <= inb;
                out1 <= (ina_reg * inb_reg);
            end if;
        end process logic;

end architecture MyHDL;

@josyb
Copy link

josyb commented Jan 20, 2016

With hindsight you'd better specify the widths as follows:

width = 9
ina, inb = [Signal(intbv(0, -2**(width-1), 2**(width-1))) for _ in range(2)]
out1 = Signal(intbv(0, -2**(2*width-1), 2**(2*width-1)))

This is easier to understand (IMHO).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment