Sébastien Bourdeauducq | 25 Jan 16:49 2015
Picon

[M-Labs devel] ARTIQ on NIST news

Hi,

NIST has published a press release on the experiment control system
we've been working on:
http://nist.gov/pml/div688/grp10/open-source-software-for-quantum-information.cfm

ARTIQ is fully open source and uses Migen/MiSoC for the gateware.

Sébastien
_______________________________________________
M-Labs devel mailing list
https://ssl.serverraum.org/lists/listinfo/devel
haimag ren | 15 Jan 02:02 2015
Picon

[M-Labs devel] Tachyon DA's CVC Full 1364 Verilog HDL Compiled Simulator is now Open Source

 Tachyon DA's CVC Full 1364 Verilog HDL Compiled Simulator is now Open Source


What is CVC?
---------------

CVC is a full IEEE 1364 2005 compliant Verilog Hardware Description Language (HDL) simulator that compilesVerilog to native X86_64 machine instructions which are executed as a simple native Linux binary.  CVC is as least as fast as any commercial full 1364 2005 simulator.
CVC Features
Fast native compiled simulation.
Very large gate and RTL capacity with 64 bit CVC64.  64 bit simulation is faster than 32 bit on modern hardware at the cost of larger cvcsim binary files.
Best solution for machine generated Verilog simulation.
Implements new  X-propagation synthesizable Verilog expression evaluation algorithm.
Linux X86 support.
Ability to simulate in either compiled or interpreted mode.
Interpreted mode allows for fast elaboration of large designs during the initial design phase. Flow graph machine code generation and optimization steps are removed to speed up elaboration.
Then when simulation speed is important, CVC compiles into a native binary that executes faster than any available simulator.
Built in toggle coverage with per instance/bit and tick period control.
VCD/EVCD/FST design state dump formats.
Latest FST output for close GTKWave integration.  Options that allow using up to 2 additional X86 cores for parallel FST generation.
Full PLI (vpi_*, dpi_*, acc_*, tf_*) support.
Fastest vpi_ and no overhead dpi_ ABI interface to c/c++.
Fully IEEE Verilog 1364-2005 standard compliant.
2-state simulation.
C compiler style simple compilation to executable – no projects and no 3 step design loading.
<div>
<div>
<h1>
<span>&nbsp;Tachyon DA's CVC Full 1364 Verilog HDL Compiled Simulator is now Open Source</span><br>
</h1>
<br>
</div>
<div class="t_msgfontfix"><table cellspacing="0" cellpadding="0"><tr><td class="t_msgfont"><span>What is CVC?<br>---------------<br><br>CVC is a full IEEE 1364 2005 compliant Verilog Hardware Description Language (HDL) simulator that compilesVerilog to native X86_64 machine instructions which are executed as a simple native Linux binary.&nbsp;&nbsp;CVC is as least as fast as any commercial full 1364 2005 simulator.<br>CVC Features<br>Fast native compiled simulation.<br>Very large gate and RTL capacity with 64 bit CVC64.&nbsp;&nbsp;64 bit simulation is faster than 32 bit on modern hardware at the cost of larger cvcsim binary files.<br>Best solution for machine generated Verilog simulation.<br>Implements new&nbsp;&nbsp;X-propagation synthesizable Verilog expression evaluation algorithm.<br>Linux X86 support.<br>Ability to simulate in either compiled or interpreted mode.<br>Interpreted mode allows for fast elaboration of large designs during the initial design phase. Flow graph machine code generation and optimization steps are removed to speed up elaboration.<br>Then when simulation speed is important, CVC compiles into a native binary that executes faster than any available simulator.<br>Built in toggle coverage with per instance/bit and tick period control.<br>VCD/EVCD/FST design state dump formats.<br>Latest FST output for close GTKWave integration.&nbsp;&nbsp;Options that allow using up to 2 additional X86 cores for parallel FST generation.<br>Full PLI (vpi_*, dpi_*, acc_*, tf_*) support.<br>Fastest vpi_ and no overhead dpi_ ABI interface to c/c++.<br>Fully IEEE Verilog 1364-2005 standard compliant.<br>2-state simulation.<br>C compiler style simple compilation to executable &ndash; no projects and no 3 step design&nbsp;<span href="tag.php?name=loading" class="t_tag">loading</span>.</span></td></tr></table></div>
</div>
Andreas | 14 Jan 15:49 2015
Picon

[M-Labs devel] WTB: The Milkymist One

Dear fellow Milkymist One users

I’m maybe looking for a second hand ”The Milkymist One” depending on price.

 

Any offers?

 

Kind regards

Andreas

 

<div><div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Dear fellow Milkymist One users<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">I&rsquo;m maybe looking for a second hand &rdquo;The Milkymist One&rdquo; depending on price.<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Any offers?<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Kind regards<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">Andreas<p></p></span></p>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div></div>
Sébastien Bourdeauducq | 14 Jan 10:15 2015
Picon

[M-Labs devel] Fwd: Re: Going to realease Yosys 0.4 soon -- please test

FYI

-------- Forwarded Message --------
Subject: Re: Going to realease Yosys 0.4 soon -- please test
Date: Tue, 13 Jan 2015 13:49:03 +0100
From: Clifford Wolf <clifford@...>
To: Sébastien Bourdeauducq <sb@...>

Hi Sébastien,

On Sun, Oct 26, 2014 at 03:59:13PM +0800, Sébastien Bourdeauducq wrote:
> On 10/26/2014 04:00 PM, Clifford Wolf wrote:
> > one of my main goals for the next release (yosys 0.5) is improved support
> > for xilinx synthesis. i.e. support for the various memory resources (from
> > SLICEM cells to BRAM36) and better support for adder synthesis (maybe very
> > basic support for DSP48 cells as well).
> 
> Great. looking forward to that!

just a short update on that: I can now synthesize the lm32 cpu for Xilinx
FPGAs with current Yosys git head [1]. It passed my lm32 testbench.  This
are the resources used:

     FDRE                         4171
     LUT1                            5
     LUT2                          468
     LUT3                         3105
     LUT4                         1569
     LUT5                          765
     LUT6                         2380
     RAMB18E1                       10

Xilinx Vivado 2014.4 reports a max path delay of 6.363ns for the created
netlist when targeting 7k70t-fbg676 in speed grade -3.

This is all very experimental. I can't create edif netlists with RAMB18E1
instances yet because at the moment write_edif does not support cell ports
that are wider than 1 bit. But this are details that should be resolved
easily before the Yosys 0.5 release.

regards,
 - clifford

[1] Takes about 13 seconds on an AMD FX-8150 at 1.4 GHz. I've seen tools
that can't check their licence in this time. I'm very proud..  :-)

--

-- 
If you are the smartest person in the room, you are in the wrong room.

Carlos Ivan CAMARGO BAREño | 11 Dec 21:19 2014
Picon

[M-Labs devel] Fwd: MiSoC Booting from internal memory



Hello

I'm trying to write to sd without format, but I can't make works my memcard_writeblock function

static int memcard_writeblock(unsigned int block, void *buffer)
{
    unsigned char b[6];

    /* CMD24 - read block */
    memcard_start_cmd_tx();
    memcard_send_command(24, block*512);
    memcard_start_cmd_dat_rx();
    if(!memcard_send_command_data(b, (unsigned int *)buffer)) return 0;
    return 1;
}


memcard_send_command just send the 512 bytes to dat_data


someone has been able to record data using memcard?


Best regards



Carlos


On Thu, Dec 4, 2014 at 9:30 AM, Sébastien Bourdeauducq <sb-Pe20TediuEBaa/9Udqfwiw@public.gmane.org> wrote:
Yes but you have to do the programming yourself.

Sébastien


On 12/04/2014 09:31 PM, Carlos Ivan CAMARGO BAREño wrote:
> Hello
>
> I`ve already boot from internal bram thanks.
>
> Right now I need to use a 32GB memory card for storage without linux (I
> can't make works my 16 bits DDR ram :( )
> But the controller uses FAT16 so I'am limited to 2GB memory cards.
>
> How can I add Fat32 support ? Is this possible?
>
> Best Regards
>
>
> Carlos
>
>
> On Mon, Nov 24, 2014 at 10:19 PM, Carlos Ivan CAMARGO BAREño
> <cicamargoba-806IAjFJSxTQFizaE/u3fw@public.gmane.org <mailto:cicamargoba-806IAjFJSxTQFizaE/u3fw@public.gmane.org>> wrote:
>
>     Thanks
>
>     Best regards
>
>     Carlos
>
>
>
>
>     On Monday, November 24, 2014, Sébastien Bourdeauducq <sb-Pe20TediuEBaa/9Udqfwiw@public.gmane.org
>     <mailto:sb-Pe20TediuEBaa/9Udqfwiw@public.gmane.org>> wrote:
>     > On 11/25/2014 05:42 AM, Carlos Ivan CAMARGO BAREño wrote:
>     >> There is an example of how to boot MiSoC using internal memory?
>     >
>     >
>     https://github.com/m-labs/misoc/commit/f7a7137127a8a1b79e39ef9e935b7b151e437ac7
>     >
>     > Sébastien
>     >
>     >
>
>



<div><div dir="ltr">
<br><div class="gmail_quote">
<br><div dir="ltr">
<div>
<div>
<div>Hello<br><br>
</div>I'm trying to write to sd without format, but I can't make works my memcard_writeblock function<br><br>static int memcard_writeblock(unsigned int block, void *buffer)<br>{<br>&nbsp;&nbsp;&nbsp; unsigned char b[6];<br><br>&nbsp;&nbsp;&nbsp; /* CMD24 - read block */<br>&nbsp;&nbsp;&nbsp; memcard_start_cmd_tx();<br>&nbsp;&nbsp;&nbsp; memcard_send_command(24, block*512);<br>&nbsp;&nbsp;&nbsp; memcard_start_cmd_dat_rx();<br>&nbsp;&nbsp;&nbsp; if(!memcard_send_command_data(b, (unsigned int *)buffer)) return 0;<br>&nbsp;&nbsp;&nbsp; return 1;<br>}<br><br><br>
</div>memcard_send_command just send the 512 bytes to dat_data<br><br><br><span lang="en"><span>someone has</span> <span>been able to record</span> <span>data using</span> <span>memcard?<br><br><br></span></span>
</div>
<div><span lang="en"><span>Best regards<span class="HOEnZb"><br><br><br><br>Carlos<br><br></span></span></span></div>
</div>
<div class="HOEnZb"><div class="h5">
<div class="gmail_extra">
<br><div class="gmail_quote">On Thu, Dec 4, 2014 at 9:30 AM, S&eacute;bastien Bourdeauducq <span dir="ltr">&lt;<a href="mailto:sb@..." target="_blank">sb@...</a>&gt;</span> wrote:<br><blockquote class="gmail_quote">Yes but you have to do the programming yourself.<br><span><br>
S&eacute;bastien<br></span><span><br><br>
On 12/04/2014 09:31 PM, Carlos Ivan CAMARGO BARE&ntilde;o wrote:<br>
&gt; Hello<br>
&gt;<br>
&gt; I`ve already boot from internal bram thanks.<br>
&gt;<br>
&gt; Right now I need to use a 32GB memory card for storage without linux (I<br>
&gt; can't make works my 16 bits DDR ram :( )<br>
&gt; But the controller uses FAT16 so I'am limited to 2GB memory cards.<br>
&gt;<br>
&gt; How can I add Fat32 support ? Is this possible?<br>
&gt;<br>
&gt; Best Regards<br>
&gt;<br>
&gt;<br>
&gt; Carlos<br>
&gt;<br>
&gt;<br>
&gt; On Mon, Nov 24, 2014 at 10:19 PM, Carlos Ivan CAMARGO BARE&ntilde;o<br></span><span>&gt; &lt;<a href="mailto:cicamargoba@..." target="_blank">cicamargoba@...</a> &lt;mailto:<a href="mailto:cicamargoba <at> unal.edu.co" target="_blank">cicamargoba@...</a>&gt;&gt; wrote:<br>
&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;Thanks<br>
&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;Best regards<br>
&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;Carlos<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;On Monday, November 24, 2014, S&eacute;bastien Bourdeauducq &lt;<a href="mailto:sb@..." target="_blank">sb@...</a><br></span><div><div>&gt;&nbsp; &nbsp; &nbsp;&lt;mailto:<a href="mailto:sb <at> m-labs.hk" target="_blank">sb@...</a>&gt;&gt; wrote:<br>
&gt;&nbsp; &nbsp; &nbsp;&gt; On 11/25/2014 05:42 AM, Carlos Ivan CAMARGO BARE&ntilde;o wrote:<br>
&gt;&nbsp; &nbsp; &nbsp;&gt;&gt; There is an example of how to boot MiSoC using internal memory?<br>
&gt;&nbsp; &nbsp; &nbsp;&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;<a href="https://github.com/m-labs/misoc/commit/f7a7137127a8a1b79e39ef9e935b7b151e437ac7" target="_blank">https://github.com/m-labs/misoc/commit/f7a7137127a8a1b79e39ef9e935b7b151e437ac7</a><br>
&gt;&nbsp; &nbsp; &nbsp;&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;&gt; S&eacute;bastien<br>
&gt;&nbsp; &nbsp; &nbsp;&gt;<br>
&gt;&nbsp; &nbsp; &nbsp;&gt;<br>
&gt;<br>
&gt;<br><br>
</div></div>
</blockquote>
</div>
<br>
</div>
</div></div>
</div>
<br>
</div></div>
Carlos Ivan CAMARGO BAREño | 24 Nov 22:42 2014
Picon

[M-Labs devel] MiSoC Booting from internal memory

Hello

There is an example of how to boot MiSoC using internal memory?


Carlos

<div><div dir="ltr">Hello<div><br></div>
<div>There is an example of how to boot MiSoC using internal memory?</div>
<div><br></div>
<div><br></div>
<div>Carlos</div>
<div><br></div>
</div></div>
Nathan Carter | 23 Nov 06:28 2014
Picon

[M-Labs devel] Trying to find a used Milkymist

Hi Everybody, 

I'm new to the list and am really interested in using a milkymist for visuals.  They are getting increasingly hard to find so before i go and build it myself i figured I'd ask the mailing list.  If anyone has one they aren't interested in or knows a source of one (perhaps a group buy) let me know!

thanks

Nate
<div><div dir="ltr">Hi Everybody,&nbsp;<div><br></div>
<div>I'm new to the list and am really interested in using a milkymist for visuals.&nbsp; They are getting increasingly hard to find so before i go and build it myself i figured I'd ask the mailing list.&nbsp; If anyone has one they aren't interested in or knows a source of one (perhaps a group buy) let me know!</div>
<div><br></div>
<div>thanks</div>
<div><br></div>
<div>Nate</div>
</div></div>
Carlos Ivan CAMARGO BAREño | 21 Nov 04:26 2014
Picon

[M-Labs devel] HPDMC 16 bit data bus

Hello 
My name is Carlos Camargo, I`ve been working with milkymist core since 3 years for my courses. Right now I want to use a pipistrello (spartan6) board with 16 bit sdram memory.

Is possible use HPDMC with 16 bus data bus?
There is a similar board using it?
There is a spartan 6 version of wb_ddr?


Best Reagards


Carlos


<div><div dir="ltr">Hello&nbsp;<div>My name is Carlos Camargo, I`ve been working with milkymist core since 3 years for my courses. Right now I want to use a&nbsp;pipistrello (spartan6) board with 16 bit sdram memory.</div>
<div><br></div>
<div>Is possible use HPDMC with 16 bus data bus?</div>
<div>There is a similar board using it?</div>
<div>There is a spartan 6 version of wb_ddr?</div>
<div><br></div>
<div><br></div>
<div>Best Reagards</div>
<div><br></div>
<div><br></div>
<div>Carlos</div>
<div><br></div>
<div><br></div>
</div></div>
Guy Hutchison | 5 Nov 20:14 2014
Picon

[M-Labs devel] [PATCH] Reformatted patch for hamming code generation

Reformatted code per comments, except for new-format string generation which I need to read up on.

- Guy
From b7f0dee52c80cf17563e4aed6428680adaa78811 Mon Sep 17 00:00:00 2001
From: Guy Hutchison <guy <at> xpliant.com>
Date: Thu, 21 Aug 2014 15:31:02 -0700
Subject: [PATCH] Added hamming-code gen/check lib

---
 migen/genlib/mhamgen.py | 272 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 272 insertions(+)
 create mode 100755 migen/genlib/mhamgen.py

diff --git a/migen/genlib/mhamgen.py b/migen/genlib/mhamgen.py
new file mode 100755
index 0000000..88a9fcd
--- /dev/null
+++ b/migen/genlib/mhamgen.py
 <at>  <at>  -0,0 +1,272  <at>  <at> 
+#!/usr/bin/env python3
+
+# Copyright (c) 2014 Guy Hutchison
+
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+
+# 1. Redistributions of source code must retain the above copyright notice, this
+#    list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import migen
+import operator
+import argparse
+from migen.fhdl.std import *
+from migen.fhdl.verilog import convert
+
+
+# Base class for Hamming code generator/checker.
+
+# build_seq() is used to create the selection of bits which need
+# to be checked for a particular data parity bit.
+
+# build_bits() is used for the generator portion, it combines the
+# bit sequences for all input and parity bits which are used and
+# removes redundant terms.
+
+# xor_tree() takes a signal and a list of bits to be applied from
+# the signal and generates a balanced xor tree as output.
+class mhamming(Module):
+    def __init__(self):
+
+        pass
+
+    def calc_code_bits(self, dataBits):
+        m = 1
+        c = 0
+
+        while (c < dataBits):
+            m += 1
+            c = 2**m - m - 1
+        return m
+
+    def build_seq(self, bnum, out_width):
+        tmp = []
+
+        ptr = 0
+        cur = 0
+        skip = 2**(bnum)-1
+        if (skip == 0):
+            check = 2**(bnum)
+        else:
+            check = 0
+        while (cur < out_width):
+            if (check > 0):
+                if (cur != 2**(bnum)-1):
+                    tmp.append(cur)
+                    ptr += 1
+                check -= 1
+                if (check == 0):
+                    skip = 2**(bnum)
+            else:
+                skip -= 1
+                if (skip == 0):
+                    check = 2**(bnum)
+            cur += 1
+
+        return tmp
+
+    # Join two lists a and b, such that redundant terms are removed
+    def join_lists(self, a, b):
+        z = []
+        for x in a+b:
+            if x not in z:
+                z.append(x)
+            else:
+                z.remove(x)
+        return z
+
+    def join_operator(self, list, op):
+        if len(list) == 0:
+            return []
+        elif len(list) == 1:
+            return list[0]
+        elif len(list) == 2:
+            return op(list[0], list[1])
+        else:
+            return op(list[0], join_operator(list[1:], op))
+
+    def xor_tree(self, in_signal, in_bits):
+        if len(in_bits) == 0:
+            print ("ERROR: in_bits must be > 0")
+        elif (len(in_bits) == 1):
+            return in_signal[in_bits[0]]
+        elif (len(in_bits) == 2):
+            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]]
+        elif (len(in_bits) == 3):
+            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]] ^ in_signal[in_bits[2]]
+        else:
+            split = int(len(in_bits)/2)
+            return self.xor_tree(in_signal, in_bits[0:split]) ^ self.xor_tree(in_signal, in_bits[split:])
+
+    def build_bits(self, in_width):
+        pnum = 1
+        innum = 0
+        blist = []
+        num_code_bits = self.calc_code_bits(in_width)
+        out_width = in_width + num_code_bits
+        v = [list()] * out_width
+        code_bit_list = []
+
+        for b in range(out_width):
+            if ((b+1) == pnum):
+                pnum = 2*pnum
+            else:
+                v[b] = [innum]
+                innum += 1
+
+        for b in range(num_code_bits):
+            vindex = 2**b-1
+            blist = self.build_seq(b, out_width)
+            for bli in blist:
+                v[vindex] = self.join_lists(v[vindex], v[bli])
+            code_bit_list.append(v[vindex])
+
+        # Calculate parity bit
+        pbit = []
+        for b in v:
+            pbit = self.join_lists(pbit, b)
+        code_bit_list.append(pbit)
+        return code_bit_list
+
+
+# Hamming code generator class
+
+# The class constructor takes a single required input, which is the number of
+# bits of the input data.  The module creates a single output, which is a set
+# of code check bits and a parity bit.
+
+# This generator and its corresponding checker will only generate a single-
+# error correct, double-error detect code.  If double-error detection is
+# not desired, the most-significant code_out bit can be left unconnected.
+
+# If generated as a top-level module, contains its suggested module name
+# in self.name and list of ports in self.ports
+class mhamgen(mhamming):
+    def __init__(self, input_size):
+        self.input_size = input_size
+        self.name = "mhamgen%03d" % input_size
+        self.data_in = Signal(input_size, name='data_in')
+        self.code_out = Signal(self.calc_code_bits(input_size)+1)
+        self.ports = {self.data_in, self.code_out}
+
+    def do_finalize(self):
+        xor_bits = self.build_bits(self.input_size)
+        for b in range(len(xor_bits)):
+            self.comb += self.code_out[b].eq(self.xor_tree(self.data_in, xor_bits[b]))
+
+
+# Hamming code checker class
+
+# Constructor takes two parameters:
+#  input_size (bits of data bus, not counting check bits)
+#  correct (boolean, True if output data should be corrected)
+
+# If used as a check/correct module, the module creates an
+# enable input which can dynamically turn off error correction
+# for debug.
+
+# If double-bit detection is not desired, the most-significant
+# code_in bit can be tied to 0, and the dberr output port left
+# unconnected.
+
+# If generated as a top-level module, contains its suggested module name
+# in self.name and list of ports in self.ports
+class mhamchk(mhamming):
+    def __init__(self, input_size, correct=True):
+        self.input_size = input_size
+        self.correct = correct
+        self.name = "mhamchk%03d" % input_size
+        self.data_in = Signal(input_size, name='data_in')
+        self.code_bits = self.calc_code_bits(input_size)
+        self.code_in = Signal(self.code_bits+1)
+        self.code_out = Signal(self.code_bits)
+        self.sberr = Signal()
+        self.dberr = Signal()
+        self.ports = {self.data_in, self.code_in, self.sberr, self.dberr}
+
+        # vector of which interleaved bit position represents a particular
+        # data bit, used for error correction
+        dbits = []
+
+        # Create interleaved vector of code bits and data bits with code bits
+        # in power-of-two positions
+        pnum = 0
+        dnum = 0
+        self.par_vec = Signal(input_size+self.code_bits)
+        for b in range(input_size+self.calc_code_bits(input_size)):
+            if b+1 == 2**pnum:
+                self.comb += self.par_vec[b].eq(self.code_in[pnum])
+                pnum += 1
+            else:
+                self.comb += self.par_vec[b].eq(self.data_in[dnum])
+                dbits.append(b)
+                dnum += 1
+
+        if correct:
+            self.enable = Signal()
+            self.correct_out = Signal(input_size)
+            self.data_out = Signal(input_size, name='data_out')
+            self.ports.add(self.data_out)
+            self.ports.add(self.enable)
+            for b in range(input_size):
+                self.comb += self.correct_out[b].eq((self.code_out == (dbits[b]+1)) ^ self.data_in[b])
+            self.comb += If(self.enable, self.data_out.eq(self.correct_out)).Else(self.data_out.eq(self.data_in))
+        else:
+            self.ports.add(self.code_out)
+
+        self.comb += self.sberr.eq(self.code_out != 0)
+        parity = Signal()
+        self.comb += parity.eq(self.xor_tree(self.data_in, range(input_size)) ^
self.xor_tree(self.code_in, range(self.code_bits+1)))
+        self.comb += self.dberr.eq(~parity)
+
+    def do_finalize(self):
+        for b in range(self.calc_code_bits(self.input_size)):
+            bits = [2**b-1]
+            bits += self.build_seq(b, self.input_size+self.calc_code_bits(self.input_size))
+            self.comb += self.code_out[b].eq(self.xor_tree(self.par_vec, bits))
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-g', help="Create generator", default=False, action='store_true')
+    parser.add_argument('-c', help="Create checker", default=False, action='store_true')
+    parser.add_argument('--correct', help="Create correcting checker", default=False, action='store_true')
+    parser.add_argument('-m', "--module", help="Override module name",
+                        type=str)
+    parser.add_argument('-w', '--width', type=int, help="Generator/checker data width")
+    args = parser.parse_args()
+
+    if args.g:
+        mhg = mhamgen(args.width)
+        if args.module is not None:
+            mhg.name = args.module
+        filename = mhg.name + '.v'
+        fh = open(filename, 'w')
+        fh.write(convert(mhg, mhg.ports, name=mhg.name))
+        fh.close()
+    if args.c:
+        mhc = mhamchk(args.width, correct=args.correct)
+        if args.module is not None:
+            mhc.name = args.module
+        filename = mhc.name + '.v'
+        fh = open(filename, 'w')
+        fh.write(convert(mhc, mhc.ports, name=mhc.name))
+        fh.close()
+
+if __name__ == "__main__":
+    main()
-- 
1.8.4.2

From 72e2c04b09059a7ce2baa127dbbb188b8257a35e Mon Sep 17 00:00:00 2001
From: Guy Hutchison <guy <at> xpliant.com>
Date: Wed, 1 Oct 2014 13:01:13 +0200
Subject: [PATCH] Code cleanup to match migen coding conventions

---
 migen/genlib/mhamgen.py | 235 ++++++++++++++++++++++++------------------------
 1 file changed, 117 insertions(+), 118 deletions(-)

diff --git a/migen/genlib/mhamgen.py b/migen/genlib/mhamgen.py
index 88a9fcd..2039fa8 100755
--- a/migen/genlib/mhamgen.py
+++ b/migen/genlib/mhamgen.py
 <at>  <at>  -29,119 +29,119  <at>  <at>  from migen.fhdl.std import *
 from migen.fhdl.verilog import convert

 
-# Base class for Hamming code generator/checker.
+# Join two lists a and b, such that redundant terms are removed
+def join_lists(a, b):
+    z = []
+    for x in a+b:
+        if x not in z:
+            z.append(x)
+        else:
+            z.remove(x)
+    return z

-# build_seq() is used to create the selection of bits which need
-# to be checked for a particular data parity bit.

-# build_bits() is used for the generator portion, it combines the
-# bit sequences for all input and parity bits which are used and
-# removes redundant terms.
+def join_operator(list, op):
+    if len(list) == 0:
+        return []
+    elif len(list) == 1:
+        return list[0]
+    elif len(list) == 2:
+        return op(list[0], list[1])
+    else:
+        return op(list[0], join_operator(list[1:], op))

-# xor_tree() takes a signal and a list of bits to be applied from
-# the signal and generates a balanced xor tree as output.
-class mhamming(Module):
-    def __init__(self):
-
-        pass

-    def calc_code_bits(self, dataBits):
-        m = 1
-        c = 0
+def calc_code_bits(dataBits):
+    m = 1
+    c = 0

-        while (c < dataBits):
-            m += 1
-            c = 2**m - m - 1
-        return m
+    while (c < dataBits):
+        m += 1
+        c = 2**m - m - 1
+    return m

-    def build_seq(self, bnum, out_width):
-        tmp = []

-        ptr = 0
-        cur = 0
-        skip = 2**(bnum)-1
-        if (skip == 0):
-            check = 2**(bnum)
-        else:
-            check = 0
-        while (cur < out_width):
-            if (check > 0):
-                if (cur != 2**(bnum)-1):
-                    tmp.append(cur)
-                    ptr += 1
-                check -= 1
-                if (check == 0):
-                    skip = 2**(bnum)
-            else:
-                skip -= 1
-                if (skip == 0):
-                    check = 2**(bnum)
-            cur += 1
-
-        return tmp
-
-    # Join two lists a and b, such that redundant terms are removed
-    def join_lists(self, a, b):
-        z = []
-        for x in a+b:
-            if x not in z:
-                z.append(x)
-            else:
-                z.remove(x)
-        return z
-
-    def join_operator(self, list, op):
-        if len(list) == 0:
-            return []
-        elif len(list) == 1:
-            return list[0]
-        elif len(list) == 2:
-            return op(list[0], list[1])
-        else:
-            return op(list[0], join_operator(list[1:], op))
-
-    def xor_tree(self, in_signal, in_bits):
-        if len(in_bits) == 0:
-            print ("ERROR: in_bits must be > 0")
-        elif (len(in_bits) == 1):
-            return in_signal[in_bits[0]]
-        elif (len(in_bits) == 2):
-            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]]
-        elif (len(in_bits) == 3):
-            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]] ^ in_signal[in_bits[2]]
+# build_seq() is used to create the selection of bits which need
+# to be checked for a particular data parity bit.
+def build_seq(bnum, out_width):
+    tmp = []
+
+    ptr = 0
+    cur = 0
+    skip = 2**(bnum)-1
+    if (skip == 0):
+        check = 2**(bnum)
+    else:
+        check = 0
+    while (cur < out_width):
+        if (check > 0):
+            if (cur != 2**(bnum)-1):
+                tmp.append(cur)
+                ptr += 1
+            check -= 1
+            if (check == 0):
+                skip = 2**(bnum)
         else:
-            split = int(len(in_bits)/2)
-            return self.xor_tree(in_signal, in_bits[0:split]) ^ self.xor_tree(in_signal, in_bits[split:])
-
-    def build_bits(self, in_width):
-        pnum = 1
-        innum = 0
-        blist = []
-        num_code_bits = self.calc_code_bits(in_width)
-        out_width = in_width + num_code_bits
-        v = [list()] * out_width
-        code_bit_list = []
-
-        for b in range(out_width):
-            if ((b+1) == pnum):
-                pnum = 2*pnum
-            else:
-                v[b] = [innum]
-                innum += 1
+            skip -= 1
+            if (skip == 0):
+                check = 2**(bnum)
+        cur += 1

-        for b in range(num_code_bits):
-            vindex = 2**b-1
-            blist = self.build_seq(b, out_width)
-            for bli in blist:
-                v[vindex] = self.join_lists(v[vindex], v[bli])
-            code_bit_list.append(v[vindex])
+    return tmp

-        # Calculate parity bit
+
+# build_bits() is used for the generator portion, it combines the
+# bit sequences for all input and parity bits which are used and
+# removes redundant terms.
+def build_bits(in_width, gen_parity=True):
+    pnum = 1
+    innum = 0
+    blist = []
+    num_code_bits = calc_code_bits(in_width)
+    out_width = in_width + num_code_bits
+    v = [list()] * out_width
+    code_bit_list = []
+
+    for b in range(out_width):
+        if ((b+1) == pnum):
+            pnum = 2*pnum
+        else:
+            v[b] = [innum]
+            innum += 1
+
+    for b in range(num_code_bits):
+        vindex = 2**b-1
+        blist = build_seq(b, out_width)
+        for bli in blist:
+            v[vindex] = join_lists(v[vindex], v[bli])
+        code_bit_list.append(v[vindex])
+
+    # Calculate parity bit
+    if gen_parity:
         pbit = []
         for b in v:
-            pbit = self.join_lists(pbit, b)
+            pbit = join_lists(pbit, b)
         code_bit_list.append(pbit)
-        return code_bit_list
+    return code_bit_list
+
+
+# xor_tree() takes a signal and a list of bits to be applied from
+# the signal and generates a balanced xor tree as output.
+def xor_tree(in_signal, in_bits):
+    if len(in_bits) == 0:
+        print ("ERROR: in_bits must be > 0")
+    elif (len(in_bits) == 1):
+        return in_signal[in_bits[0]]
+    elif (len(in_bits) == 2):
+        return in_signal[in_bits[0]] ^ in_signal[in_bits[1]]
+    elif (len(in_bits) == 3):
+        return in_signal[in_bits[0]] ^ in_signal[in_bits[1]] ^ in_signal[in_bits[2]]
+    else:
+        split = int(len(in_bits)/2)
+        return xor_tree(in_signal, in_bits[0:split]) ^ xor_tree(in_signal, in_bits[split:])
+
+
+# Base class for Hamming code generator/checker.

 
 # Hamming code generator class
 <at>  <at>  -156,18 +156,17  <at>  <at>  class mhamming(Module):

 # If generated as a top-level module, contains its suggested module name
 # in self.name and list of ports in self.ports
-class mhamgen(mhamming):
+class HammingGenerator(Module):
     def __init__(self, input_size):
         self.input_size = input_size
         self.name = "mhamgen%03d" % input_size
-        self.data_in = Signal(input_size, name='data_in')
-        self.code_out = Signal(self.calc_code_bits(input_size)+1)
+        self.data_in = Signal(input_size, name_override='data_in')
+        self.code_out = Signal(calc_code_bits(input_size)+1)
         self.ports = {self.data_in, self.code_out}

-    def do_finalize(self):
-        xor_bits = self.build_bits(self.input_size)
+        xor_bits = build_bits(self.input_size)
         for b in range(len(xor_bits)):
-            self.comb += self.code_out[b].eq(self.xor_tree(self.data_in, xor_bits[b]))
+            self.comb += self.code_out[b].eq(xor_tree(self.data_in, xor_bits[b]))

 
 # Hamming code checker class
 <at>  <at>  -186,17 +185,18  <at>  <at>  class mhamgen(mhamming):

 # If generated as a top-level module, contains its suggested module name
 # in self.name and list of ports in self.ports
-class mhamchk(mhamming):
-    def __init__(self, input_size, correct=True):
+class HammingChecker(Module):
+    def __init__(self, input_size, correct=True, parity=True):
         self.input_size = input_size
         self.correct = correct
         self.name = "mhamchk%03d" % input_size
-        self.data_in = Signal(input_size, name='data_in')
-        self.code_bits = self.calc_code_bits(input_size)
+        self.data_in = Signal(input_size, name_override='data_in')
+        self.code_bits = calc_code_bits(input_size)
         self.code_in = Signal(self.code_bits+1)
         self.code_out = Signal(self.code_bits)
         self.sberr = Signal()
-        self.dberr = Signal()
+        if parity:
+            self.dberr = Signal()
         self.ports = {self.data_in, self.code_in, self.sberr, self.dberr}

         # vector of which interleaved bit position represents a particular
 <at>  <at>  -208,7 +208,7  <at>  <at>  class mhamchk(mhamming):
         pnum = 0
         dnum = 0
         self.par_vec = Signal(input_size+self.code_bits)
-        for b in range(input_size+self.calc_code_bits(input_size)):
+        for b in range(input_size+calc_code_bits(input_size)):
             if b+1 == 2**pnum:
                 self.comb += self.par_vec[b].eq(self.code_in[pnum])
                 pnum += 1
 <at>  <at>  -234,11 +234,10  <at>  <at>  class mhamchk(mhamming):
         self.comb += parity.eq(self.xor_tree(self.data_in, range(input_size)) ^
self.xor_tree(self.code_in, range(self.code_bits+1)))
         self.comb += self.dberr.eq(~parity)

-    def do_finalize(self):
-        for b in range(self.calc_code_bits(self.input_size)):
+        for b in range(calc_code_bits(self.input_size)):
             bits = [2**b-1]
-            bits += self.build_seq(b, self.input_size+self.calc_code_bits(self.input_size))
-            self.comb += self.code_out[b].eq(self.xor_tree(self.par_vec, bits))
+            bits += build_seq(b, self.input_size+calc_code_bits(self.input_size))
+            self.comb += self.code_out[b].eq(xor_tree(self.par_vec, bits))

 
 def main():
 <at>  <at>  -252,7 +251,7  <at>  <at>  def main():
     args = parser.parse_args()

     if args.g:
-        mhg = mhamgen(args.width)
+        mhg = HammingGenerator(args.width)
         if args.module is not None:
             mhg.name = args.module
         filename = mhg.name + '.v'
 <at>  <at>  -260,7 +259,7  <at>  <at>  def main():
         fh.write(convert(mhg, mhg.ports, name=mhg.name))
         fh.close()
     if args.c:
-        mhc = mhamchk(args.width, correct=args.correct)
+        mhc = HammingChecker(args.width, correct=args.correct)
         if args.module is not None:
             mhc.name = args.module
         filename = mhc.name + '.v'
-- 
1.8.4.2

From 8dc0ee74f56f995826bcd8385b3e45727d607ba3 Mon Sep 17 00:00:00 2001
From: Guy Hutchison <guy <at> xpliant.com>
Date: Wed, 5 Nov 2014 09:18:00 -0800
Subject: [PATCH] Modified code for project commit

---
 migen/genlib/mhamgen.py | 49 +++++++++++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/migen/genlib/mhamgen.py b/migen/genlib/mhamgen.py
index 2039fa8..56de6e0 100755
--- a/migen/genlib/mhamgen.py
+++ b/migen/genlib/mhamgen.py
 <at>  <at>  -159,10 +159,8  <at>  <at>  def xor_tree(in_signal, in_bits):
 class HammingGenerator(Module):
     def __init__(self, input_size):
         self.input_size = input_size
-        self.name = "mhamgen%03d" % input_size
-        self.data_in = Signal(input_size, name_override='data_in')
+        self.data_in = Signal(input_size)
         self.code_out = Signal(calc_code_bits(input_size)+1)
-        self.ports = {self.data_in, self.code_out}

         xor_bits = build_bits(self.input_size)
         for b in range(len(xor_bits)):
 <at>  <at>  -186,18 +184,16  <at>  <at>  class HammingGenerator(Module):
 # If generated as a top-level module, contains its suggested module name
 # in self.name and list of ports in self.ports
 class HammingChecker(Module):
-    def __init__(self, input_size, correct=True, parity=True):
+    def __init__(self, input_size, correct=True, gen_parity=True):
         self.input_size = input_size
         self.correct = correct
-        self.name = "mhamchk%03d" % input_size
-        self.data_in = Signal(input_size, name_override='data_in')
+        self.data_in = Signal(input_size)
         self.code_bits = calc_code_bits(input_size)
         self.code_in = Signal(self.code_bits+1)
         self.code_out = Signal(self.code_bits)
         self.sberr = Signal()
-        if parity:
+        if gen_parity:
             self.dberr = Signal()
-        self.ports = {self.data_in, self.code_in, self.sberr, self.dberr}

         # vector of which interleaved bit position represents a particular
         # data bit, used for error correction
 <at>  <at>  -221,18 +217,15  <at>  <at>  class HammingChecker(Module):
             self.enable = Signal()
             self.correct_out = Signal(input_size)
             self.data_out = Signal(input_size, name='data_out')
-            self.ports.add(self.data_out)
-            self.ports.add(self.enable)
             for b in range(input_size):
                 self.comb += self.correct_out[b].eq((self.code_out == (dbits[b]+1)) ^ self.data_in[b])
             self.comb += If(self.enable, self.data_out.eq(self.correct_out)).Else(self.data_out.eq(self.data_in))
-        else:
-            self.ports.add(self.code_out)

         self.comb += self.sberr.eq(self.code_out != 0)
-        parity = Signal()
-        self.comb += parity.eq(self.xor_tree(self.data_in, range(input_size)) ^
self.xor_tree(self.code_in, range(self.code_bits+1)))
-        self.comb += self.dberr.eq(~parity)
+        if gen_parity:
+            parity = Signal()
+            self.comb += parity.eq(xor_tree(self.data_in, range(input_size)) ^ xor_tree(self.code_in, range(self.code_bits+1)))
+            self.comb += self.dberr.eq(~parity)

         for b in range(calc_code_bits(self.input_size)):
             bits = [2**b-1]
 <at>  <at>  -244,27 +237,43  <at>  <at>  def main():
     parser = argparse.ArgumentParser()
     parser.add_argument('-g', help="Create generator", default=False, action='store_true')
     parser.add_argument('-c', help="Create checker", default=False, action='store_true')
+    parser.add_argument('--noparity', help="Create without parity check", default=False, action='store_true')
     parser.add_argument('--correct', help="Create correcting checker", default=False, action='store_true')
     parser.add_argument('-m', "--module", help="Override module name",
                         type=str)
     parser.add_argument('-w', '--width', type=int, help="Generator/checker data width")
     args = parser.parse_args()
+    parity = not args.noparity

     if args.g:
         mhg = HammingGenerator(args.width)
+        ports = {mhg.data_in, mhg.code_out}
+        mhg.data_in.name_override = "data_in"
         if args.module is not None:
-            mhg.name = args.module
-        filename = mhg.name + '.v'
+            name = args.module
+        else:
+            name = "mhamgen%03d" % args.width
+        filename = name + '.v'
         fh = open(filename, 'w')
-        fh.write(convert(mhg, mhg.ports, name=mhg.name))
+        fh.write(convert(mhg, ports, name=name))
         fh.close()
     if args.c:
         mhc = HammingChecker(args.width, correct=args.correct)
+        ports = {mhc.data_in, mhc.code_in, mhc.sberr, mhc.dberr}
+        if args.correct:
+            ports.add(mhc.data_out)
+            ports.add(mhc.enable)
+        else:
+            ports.add(mhc.code_out)
+        if parity:
+            ports.add(mhc.dberr)
         if args.module is not None:
             mhc.name = args.module
-        filename = mhc.name + '.v'
+        else:
+            name = "mhamchk%03d" % args.width
+        filename = name + '.v'
         fh = open(filename, 'w')
-        fh.write(convert(mhc, mhc.ports, name=mhc.name))
+        fh.write(convert(mhc, ports, name=name))
         fh.close()

 if __name__ == "__main__":
-- 
1.8.4.2

From b7f0dee52c80cf17563e4aed6428680adaa78811 Mon Sep 17 00:00:00 2001
From: Guy Hutchison <guy <at> xpliant.com>
Date: Thu, 21 Aug 2014 15:31:02 -0700
Subject: [PATCH] Added hamming-code gen/check lib

---
 migen/genlib/mhamgen.py | 272 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 272 insertions(+)
 create mode 100755 migen/genlib/mhamgen.py

diff --git a/migen/genlib/mhamgen.py b/migen/genlib/mhamgen.py
new file mode 100755
index 0000000..88a9fcd
--- /dev/null
+++ b/migen/genlib/mhamgen.py
 <at>  <at>  -0,0 +1,272  <at>  <at> 
+#!/usr/bin/env python3
+
+# Copyright (c) 2014 Guy Hutchison
+
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+
+# 1. Redistributions of source code must retain the above copyright notice, this
+#    list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import migen
+import operator
+import argparse
+from migen.fhdl.std import *
+from migen.fhdl.verilog import convert
+
+
+# Base class for Hamming code generator/checker.
+
+# build_seq() is used to create the selection of bits which need
+# to be checked for a particular data parity bit.
+
+# build_bits() is used for the generator portion, it combines the
+# bit sequences for all input and parity bits which are used and
+# removes redundant terms.
+
+# xor_tree() takes a signal and a list of bits to be applied from
+# the signal and generates a balanced xor tree as output.
+class mhamming(Module):
+    def __init__(self):
+
+        pass
+
+    def calc_code_bits(self, dataBits):
+        m = 1
+        c = 0
+
+        while (c < dataBits):
+            m += 1
+            c = 2**m - m - 1
+        return m
+
+    def build_seq(self, bnum, out_width):
+        tmp = []
+
+        ptr = 0
+        cur = 0
+        skip = 2**(bnum)-1
+        if (skip == 0):
+            check = 2**(bnum)
+        else:
+            check = 0
+        while (cur < out_width):
+            if (check > 0):
+                if (cur != 2**(bnum)-1):
+                    tmp.append(cur)
+                    ptr += 1
+                check -= 1
+                if (check == 0):
+                    skip = 2**(bnum)
+            else:
+                skip -= 1
+                if (skip == 0):
+                    check = 2**(bnum)
+            cur += 1
+
+        return tmp
+
+    # Join two lists a and b, such that redundant terms are removed
+    def join_lists(self, a, b):
+        z = []
+        for x in a+b:
+            if x not in z:
+                z.append(x)
+            else:
+                z.remove(x)
+        return z
+
+    def join_operator(self, list, op):
+        if len(list) == 0:
+            return []
+        elif len(list) == 1:
+            return list[0]
+        elif len(list) == 2:
+            return op(list[0], list[1])
+        else:
+            return op(list[0], join_operator(list[1:], op))
+
+    def xor_tree(self, in_signal, in_bits):
+        if len(in_bits) == 0:
+            print ("ERROR: in_bits must be > 0")
+        elif (len(in_bits) == 1):
+            return in_signal[in_bits[0]]
+        elif (len(in_bits) == 2):
+            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]]
+        elif (len(in_bits) == 3):
+            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]] ^ in_signal[in_bits[2]]
+        else:
+            split = int(len(in_bits)/2)
+            return self.xor_tree(in_signal, in_bits[0:split]) ^ self.xor_tree(in_signal, in_bits[split:])
+
+    def build_bits(self, in_width):
+        pnum = 1
+        innum = 0
+        blist = []
+        num_code_bits = self.calc_code_bits(in_width)
+        out_width = in_width + num_code_bits
+        v = [list()] * out_width
+        code_bit_list = []
+
+        for b in range(out_width):
+            if ((b+1) == pnum):
+                pnum = 2*pnum
+            else:
+                v[b] = [innum]
+                innum += 1
+
+        for b in range(num_code_bits):
+            vindex = 2**b-1
+            blist = self.build_seq(b, out_width)
+            for bli in blist:
+                v[vindex] = self.join_lists(v[vindex], v[bli])
+            code_bit_list.append(v[vindex])
+
+        # Calculate parity bit
+        pbit = []
+        for b in v:
+            pbit = self.join_lists(pbit, b)
+        code_bit_list.append(pbit)
+        return code_bit_list
+
+
+# Hamming code generator class
+
+# The class constructor takes a single required input, which is the number of
+# bits of the input data.  The module creates a single output, which is a set
+# of code check bits and a parity bit.
+
+# This generator and its corresponding checker will only generate a single-
+# error correct, double-error detect code.  If double-error detection is
+# not desired, the most-significant code_out bit can be left unconnected.
+
+# If generated as a top-level module, contains its suggested module name
+# in self.name and list of ports in self.ports
+class mhamgen(mhamming):
+    def __init__(self, input_size):
+        self.input_size = input_size
+        self.name = "mhamgen%03d" % input_size
+        self.data_in = Signal(input_size, name='data_in')
+        self.code_out = Signal(self.calc_code_bits(input_size)+1)
+        self.ports = {self.data_in, self.code_out}
+
+    def do_finalize(self):
+        xor_bits = self.build_bits(self.input_size)
+        for b in range(len(xor_bits)):
+            self.comb += self.code_out[b].eq(self.xor_tree(self.data_in, xor_bits[b]))
+
+
+# Hamming code checker class
+
+# Constructor takes two parameters:
+#  input_size (bits of data bus, not counting check bits)
+#  correct (boolean, True if output data should be corrected)
+
+# If used as a check/correct module, the module creates an
+# enable input which can dynamically turn off error correction
+# for debug.
+
+# If double-bit detection is not desired, the most-significant
+# code_in bit can be tied to 0, and the dberr output port left
+# unconnected.
+
+# If generated as a top-level module, contains its suggested module name
+# in self.name and list of ports in self.ports
+class mhamchk(mhamming):
+    def __init__(self, input_size, correct=True):
+        self.input_size = input_size
+        self.correct = correct
+        self.name = "mhamchk%03d" % input_size
+        self.data_in = Signal(input_size, name='data_in')
+        self.code_bits = self.calc_code_bits(input_size)
+        self.code_in = Signal(self.code_bits+1)
+        self.code_out = Signal(self.code_bits)
+        self.sberr = Signal()
+        self.dberr = Signal()
+        self.ports = {self.data_in, self.code_in, self.sberr, self.dberr}
+
+        # vector of which interleaved bit position represents a particular
+        # data bit, used for error correction
+        dbits = []
+
+        # Create interleaved vector of code bits and data bits with code bits
+        # in power-of-two positions
+        pnum = 0
+        dnum = 0
+        self.par_vec = Signal(input_size+self.code_bits)
+        for b in range(input_size+self.calc_code_bits(input_size)):
+            if b+1 == 2**pnum:
+                self.comb += self.par_vec[b].eq(self.code_in[pnum])
+                pnum += 1
+            else:
+                self.comb += self.par_vec[b].eq(self.data_in[dnum])
+                dbits.append(b)
+                dnum += 1
+
+        if correct:
+            self.enable = Signal()
+            self.correct_out = Signal(input_size)
+            self.data_out = Signal(input_size, name='data_out')
+            self.ports.add(self.data_out)
+            self.ports.add(self.enable)
+            for b in range(input_size):
+                self.comb += self.correct_out[b].eq((self.code_out == (dbits[b]+1)) ^ self.data_in[b])
+            self.comb += If(self.enable, self.data_out.eq(self.correct_out)).Else(self.data_out.eq(self.data_in))
+        else:
+            self.ports.add(self.code_out)
+
+        self.comb += self.sberr.eq(self.code_out != 0)
+        parity = Signal()
+        self.comb += parity.eq(self.xor_tree(self.data_in, range(input_size)) ^
self.xor_tree(self.code_in, range(self.code_bits+1)))
+        self.comb += self.dberr.eq(~parity)
+
+    def do_finalize(self):
+        for b in range(self.calc_code_bits(self.input_size)):
+            bits = [2**b-1]
+            bits += self.build_seq(b, self.input_size+self.calc_code_bits(self.input_size))
+            self.comb += self.code_out[b].eq(self.xor_tree(self.par_vec, bits))
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-g', help="Create generator", default=False, action='store_true')
+    parser.add_argument('-c', help="Create checker", default=False, action='store_true')
+    parser.add_argument('--correct', help="Create correcting checker", default=False, action='store_true')
+    parser.add_argument('-m', "--module", help="Override module name",
+                        type=str)
+    parser.add_argument('-w', '--width', type=int, help="Generator/checker data width")
+    args = parser.parse_args()
+
+    if args.g:
+        mhg = mhamgen(args.width)
+        if args.module is not None:
+            mhg.name = args.module
+        filename = mhg.name + '.v'
+        fh = open(filename, 'w')
+        fh.write(convert(mhg, mhg.ports, name=mhg.name))
+        fh.close()
+    if args.c:
+        mhc = mhamchk(args.width, correct=args.correct)
+        if args.module is not None:
+            mhc.name = args.module
+        filename = mhc.name + '.v'
+        fh = open(filename, 'w')
+        fh.write(convert(mhc, mhc.ports, name=mhc.name))
+        fh.close()
+
+if __name__ == "__main__":
+    main()
-- 
1.8.4.2

From 72e2c04b09059a7ce2baa127dbbb188b8257a35e Mon Sep 17 00:00:00 2001
From: Guy Hutchison <guy <at> xpliant.com>
Date: Wed, 1 Oct 2014 13:01:13 +0200
Subject: [PATCH] Code cleanup to match migen coding conventions

---
 migen/genlib/mhamgen.py | 235 ++++++++++++++++++++++++------------------------
 1 file changed, 117 insertions(+), 118 deletions(-)

diff --git a/migen/genlib/mhamgen.py b/migen/genlib/mhamgen.py
index 88a9fcd..2039fa8 100755
--- a/migen/genlib/mhamgen.py
+++ b/migen/genlib/mhamgen.py
 <at>  <at>  -29,119 +29,119  <at>  <at>  from migen.fhdl.std import *
 from migen.fhdl.verilog import convert

 
-# Base class for Hamming code generator/checker.
+# Join two lists a and b, such that redundant terms are removed
+def join_lists(a, b):
+    z = []
+    for x in a+b:
+        if x not in z:
+            z.append(x)
+        else:
+            z.remove(x)
+    return z

-# build_seq() is used to create the selection of bits which need
-# to be checked for a particular data parity bit.

-# build_bits() is used for the generator portion, it combines the
-# bit sequences for all input and parity bits which are used and
-# removes redundant terms.
+def join_operator(list, op):
+    if len(list) == 0:
+        return []
+    elif len(list) == 1:
+        return list[0]
+    elif len(list) == 2:
+        return op(list[0], list[1])
+    else:
+        return op(list[0], join_operator(list[1:], op))

-# xor_tree() takes a signal and a list of bits to be applied from
-# the signal and generates a balanced xor tree as output.
-class mhamming(Module):
-    def __init__(self):
-
-        pass

-    def calc_code_bits(self, dataBits):
-        m = 1
-        c = 0
+def calc_code_bits(dataBits):
+    m = 1
+    c = 0

-        while (c < dataBits):
-            m += 1
-            c = 2**m - m - 1
-        return m
+    while (c < dataBits):
+        m += 1
+        c = 2**m - m - 1
+    return m

-    def build_seq(self, bnum, out_width):
-        tmp = []

-        ptr = 0
-        cur = 0
-        skip = 2**(bnum)-1
-        if (skip == 0):
-            check = 2**(bnum)
-        else:
-            check = 0
-        while (cur < out_width):
-            if (check > 0):
-                if (cur != 2**(bnum)-1):
-                    tmp.append(cur)
-                    ptr += 1
-                check -= 1
-                if (check == 0):
-                    skip = 2**(bnum)
-            else:
-                skip -= 1
-                if (skip == 0):
-                    check = 2**(bnum)
-            cur += 1
-
-        return tmp
-
-    # Join two lists a and b, such that redundant terms are removed
-    def join_lists(self, a, b):
-        z = []
-        for x in a+b:
-            if x not in z:
-                z.append(x)
-            else:
-                z.remove(x)
-        return z
-
-    def join_operator(self, list, op):
-        if len(list) == 0:
-            return []
-        elif len(list) == 1:
-            return list[0]
-        elif len(list) == 2:
-            return op(list[0], list[1])
-        else:
-            return op(list[0], join_operator(list[1:], op))
-
-    def xor_tree(self, in_signal, in_bits):
-        if len(in_bits) == 0:
-            print ("ERROR: in_bits must be > 0")
-        elif (len(in_bits) == 1):
-            return in_signal[in_bits[0]]
-        elif (len(in_bits) == 2):
-            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]]
-        elif (len(in_bits) == 3):
-            return in_signal[in_bits[0]] ^ in_signal[in_bits[1]] ^ in_signal[in_bits[2]]
+# build_seq() is used to create the selection of bits which need
+# to be checked for a particular data parity bit.
+def build_seq(bnum, out_width):
+    tmp = []
+
+    ptr = 0
+    cur = 0
+    skip = 2**(bnum)-1
+    if (skip == 0):
+        check = 2**(bnum)
+    else:
+        check = 0
+    while (cur < out_width):
+        if (check > 0):
+            if (cur != 2**(bnum)-1):
+                tmp.append(cur)
+                ptr += 1
+            check -= 1
+            if (check == 0):
+                skip = 2**(bnum)
         else:
-            split = int(len(in_bits)/2)
-            return self.xor_tree(in_signal, in_bits[0:split]) ^ self.xor_tree(in_signal, in_bits[split:])
-
-    def build_bits(self, in_width):
-        pnum = 1
-        innum = 0
-        blist = []
-        num_code_bits = self.calc_code_bits(in_width)
-        out_width = in_width + num_code_bits
-        v = [list()] * out_width
-        code_bit_list = []
-
-        for b in range(out_width):
-            if ((b+1) == pnum):
-                pnum = 2*pnum
-            else:
-                v[b] = [innum]
-                innum += 1
+            skip -= 1
+            if (skip == 0):
+                check = 2**(bnum)
+        cur += 1

-        for b in range(num_code_bits):
-            vindex = 2**b-1
-            blist = self.build_seq(b, out_width)
-            for bli in blist:
-                v[vindex] = self.join_lists(v[vindex], v[bli])
-            code_bit_list.append(v[vindex])
+    return tmp

-        # Calculate parity bit
+
+# build_bits() is used for the generator portion, it combines the
+# bit sequences for all input and parity bits which are used and
+# removes redundant terms.
+def build_bits(in_width, gen_parity=True):
+    pnum = 1
+    innum = 0
+    blist = []
+    num_code_bits = calc_code_bits(in_width)
+    out_width = in_width + num_code_bits
+    v = [list()] * out_width
+    code_bit_list = []
+
+    for b in range(out_width):
+        if ((b+1) == pnum):
+            pnum = 2*pnum
+        else:
+            v[b] = [innum]
+            innum += 1
+
+    for b in range(num_code_bits):
+        vindex = 2**b-1
+        blist = build_seq(b, out_width)
+        for bli in blist:
+            v[vindex] = join_lists(v[vindex], v[bli])
+        code_bit_list.append(v[vindex])
+
+    # Calculate parity bit
+    if gen_parity:
         pbit = []
         for b in v:
-            pbit = self.join_lists(pbit, b)
+            pbit = join_lists(pbit, b)
         code_bit_list.append(pbit)
-        return code_bit_list
+    return code_bit_list
+
+
+# xor_tree() takes a signal and a list of bits to be applied from
+# the signal and generates a balanced xor tree as output.
+def xor_tree(in_signal, in_bits):
+    if len(in_bits) == 0:
+        print ("ERROR: in_bits must be > 0")
+    elif (len(in_bits) == 1):
+        return in_signal[in_bits[0]]
+    elif (len(in_bits) == 2):
+        return in_signal[in_bits[0]] ^ in_signal[in_bits[1]]
+    elif (len(in_bits) == 3):
+        return in_signal[in_bits[0]] ^ in_signal[in_bits[1]] ^ in_signal[in_bits[2]]
+    else:
+        split = int(len(in_bits)/2)
+        return xor_tree(in_signal, in_bits[0:split]) ^ xor_tree(in_signal, in_bits[split:])
+
+
+# Base class for Hamming code generator/checker.

 
 # Hamming code generator class
 <at>  <at>  -156,18 +156,17  <at>  <at>  class mhamming(Module):

 # If generated as a top-level module, contains its suggested module name
 # in self.name and list of ports in self.ports
-class mhamgen(mhamming):
+class HammingGenerator(Module):
     def __init__(self, input_size):
         self.input_size = input_size
         self.name = "mhamgen%03d" % input_size
-        self.data_in = Signal(input_size, name='data_in')
-        self.code_out = Signal(self.calc_code_bits(input_size)+1)
+        self.data_in = Signal(input_size, name_override='data_in')
+        self.code_out = Signal(calc_code_bits(input_size)+1)
         self.ports = {self.data_in, self.code_out}

-    def do_finalize(self):
-        xor_bits = self.build_bits(self.input_size)
+        xor_bits = build_bits(self.input_size)
         for b in range(len(xor_bits)):
-            self.comb += self.code_out[b].eq(self.xor_tree(self.data_in, xor_bits[b]))
+            self.comb += self.code_out[b].eq(xor_tree(self.data_in, xor_bits[b]))

 
 # Hamming code checker class
 <at>  <at>  -186,17 +185,18  <at>  <at>  class mhamgen(mhamming):

 # If generated as a top-level module, contains its suggested module name
 # in self.name and list of ports in self.ports
-class mhamchk(mhamming):
-    def __init__(self, input_size, correct=True):
+class HammingChecker(Module):
+    def __init__(self, input_size, correct=True, parity=True):
         self.input_size = input_size
         self.correct = correct
         self.name = "mhamchk%03d" % input_size
-        self.data_in = Signal(input_size, name='data_in')
-        self.code_bits = self.calc_code_bits(input_size)
+        self.data_in = Signal(input_size, name_override='data_in')
+        self.code_bits = calc_code_bits(input_size)
         self.code_in = Signal(self.code_bits+1)
         self.code_out = Signal(self.code_bits)
         self.sberr = Signal()
-        self.dberr = Signal()
+        if parity:
+            self.dberr = Signal()
         self.ports = {self.data_in, self.code_in, self.sberr, self.dberr}

         # vector of which interleaved bit position represents a particular
 <at>  <at>  -208,7 +208,7  <at>  <at>  class mhamchk(mhamming):
         pnum = 0
         dnum = 0
         self.par_vec = Signal(input_size+self.code_bits)
-        for b in range(input_size+self.calc_code_bits(input_size)):
+        for b in range(input_size+calc_code_bits(input_size)):
             if b+1 == 2**pnum:
                 self.comb += self.par_vec[b].eq(self.code_in[pnum])
                 pnum += 1
 <at>  <at>  -234,11 +234,10  <at>  <at>  class mhamchk(mhamming):
         self.comb += parity.eq(self.xor_tree(self.data_in, range(input_size)) ^
self.xor_tree(self.code_in, range(self.code_bits+1)))
         self.comb += self.dberr.eq(~parity)

-    def do_finalize(self):
-        for b in range(self.calc_code_bits(self.input_size)):
+        for b in range(calc_code_bits(self.input_size)):
             bits = [2**b-1]
-            bits += self.build_seq(b, self.input_size+self.calc_code_bits(self.input_size))
-            self.comb += self.code_out[b].eq(self.xor_tree(self.par_vec, bits))
+            bits += build_seq(b, self.input_size+calc_code_bits(self.input_size))
+            self.comb += self.code_out[b].eq(xor_tree(self.par_vec, bits))

 
 def main():
 <at>  <at>  -252,7 +251,7  <at>  <at>  def main():
     args = parser.parse_args()

     if args.g:
-        mhg = mhamgen(args.width)
+        mhg = HammingGenerator(args.width)
         if args.module is not None:
             mhg.name = args.module
         filename = mhg.name + '.v'
 <at>  <at>  -260,7 +259,7  <at>  <at>  def main():
         fh.write(convert(mhg, mhg.ports, name=mhg.name))
         fh.close()
     if args.c:
-        mhc = mhamchk(args.width, correct=args.correct)
+        mhc = HammingChecker(args.width, correct=args.correct)
         if args.module is not None:
             mhc.name = args.module
         filename = mhc.name + '.v'
-- 
1.8.4.2

From 8dc0ee74f56f995826bcd8385b3e45727d607ba3 Mon Sep 17 00:00:00 2001
From: Guy Hutchison <guy <at> xpliant.com>
Date: Wed, 5 Nov 2014 09:18:00 -0800
Subject: [PATCH] Modified code for project commit

---
 migen/genlib/mhamgen.py | 49 +++++++++++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/migen/genlib/mhamgen.py b/migen/genlib/mhamgen.py
index 2039fa8..56de6e0 100755
--- a/migen/genlib/mhamgen.py
+++ b/migen/genlib/mhamgen.py
 <at>  <at>  -159,10 +159,8  <at>  <at>  def xor_tree(in_signal, in_bits):
 class HammingGenerator(Module):
     def __init__(self, input_size):
         self.input_size = input_size
-        self.name = "mhamgen%03d" % input_size
-        self.data_in = Signal(input_size, name_override='data_in')
+        self.data_in = Signal(input_size)
         self.code_out = Signal(calc_code_bits(input_size)+1)
-        self.ports = {self.data_in, self.code_out}

         xor_bits = build_bits(self.input_size)
         for b in range(len(xor_bits)):
 <at>  <at>  -186,18 +184,16  <at>  <at>  class HammingGenerator(Module):
 # If generated as a top-level module, contains its suggested module name
 # in self.name and list of ports in self.ports
 class HammingChecker(Module):
-    def __init__(self, input_size, correct=True, parity=True):
+    def __init__(self, input_size, correct=True, gen_parity=True):
         self.input_size = input_size
         self.correct = correct
-        self.name = "mhamchk%03d" % input_size
-        self.data_in = Signal(input_size, name_override='data_in')
+        self.data_in = Signal(input_size)
         self.code_bits = calc_code_bits(input_size)
         self.code_in = Signal(self.code_bits+1)
         self.code_out = Signal(self.code_bits)
         self.sberr = Signal()
-        if parity:
+        if gen_parity:
             self.dberr = Signal()
-        self.ports = {self.data_in, self.code_in, self.sberr, self.dberr}

         # vector of which interleaved bit position represents a particular
         # data bit, used for error correction
 <at>  <at>  -221,18 +217,15  <at>  <at>  class HammingChecker(Module):
             self.enable = Signal()
             self.correct_out = Signal(input_size)
             self.data_out = Signal(input_size, name='data_out')
-            self.ports.add(self.data_out)
-            self.ports.add(self.enable)
             for b in range(input_size):
                 self.comb += self.correct_out[b].eq((self.code_out == (dbits[b]+1)) ^ self.data_in[b])
             self.comb += If(self.enable, self.data_out.eq(self.correct_out)).Else(self.data_out.eq(self.data_in))
-        else:
-            self.ports.add(self.code_out)

         self.comb += self.sberr.eq(self.code_out != 0)
-        parity = Signal()
-        self.comb += parity.eq(self.xor_tree(self.data_in, range(input_size)) ^
self.xor_tree(self.code_in, range(self.code_bits+1)))
-        self.comb += self.dberr.eq(~parity)
+        if gen_parity:
+            parity = Signal()
+            self.comb += parity.eq(xor_tree(self.data_in, range(input_size)) ^ xor_tree(self.code_in, range(self.code_bits+1)))
+            self.comb += self.dberr.eq(~parity)

         for b in range(calc_code_bits(self.input_size)):
             bits = [2**b-1]
 <at>  <at>  -244,27 +237,43  <at>  <at>  def main():
     parser = argparse.ArgumentParser()
     parser.add_argument('-g', help="Create generator", default=False, action='store_true')
     parser.add_argument('-c', help="Create checker", default=False, action='store_true')
+    parser.add_argument('--noparity', help="Create without parity check", default=False, action='store_true')
     parser.add_argument('--correct', help="Create correcting checker", default=False, action='store_true')
     parser.add_argument('-m', "--module", help="Override module name",
                         type=str)
     parser.add_argument('-w', '--width', type=int, help="Generator/checker data width")
     args = parser.parse_args()
+    parity = not args.noparity

     if args.g:
         mhg = HammingGenerator(args.width)
+        ports = {mhg.data_in, mhg.code_out}
+        mhg.data_in.name_override = "data_in"
         if args.module is not None:
-            mhg.name = args.module
-        filename = mhg.name + '.v'
+            name = args.module
+        else:
+            name = "mhamgen%03d" % args.width
+        filename = name + '.v'
         fh = open(filename, 'w')
-        fh.write(convert(mhg, mhg.ports, name=mhg.name))
+        fh.write(convert(mhg, ports, name=name))
         fh.close()
     if args.c:
         mhc = HammingChecker(args.width, correct=args.correct)
+        ports = {mhc.data_in, mhc.code_in, mhc.sberr, mhc.dberr}
+        if args.correct:
+            ports.add(mhc.data_out)
+            ports.add(mhc.enable)
+        else:
+            ports.add(mhc.code_out)
+        if parity:
+            ports.add(mhc.dberr)
         if args.module is not None:
             mhc.name = args.module
-        filename = mhc.name + '.v'
+        else:
+            name = "mhamchk%03d" % args.width
+        filename = name + '.v'
         fh = open(filename, 'w')
-        fh.write(convert(mhc, mhc.ports, name=mhc.name))
+        fh.write(convert(mhc, ports, name=name))
         fh.close()

 if __name__ == "__main__":
--

-- 
1.8.4.2

Tobias Strauch | 4 Nov 14:26 2014

[M-Labs devel] board pdf

Hi folks,
 
your projects look outstanding and I would love to dig into it a little bit more.
 
Unfort. I cannot open the Eagle files of your board-m1 files. May I ask you if you can send me  or release the pdf version as well. I'm interested how you connected the DVI to the FPGA.
 
Thanks a lot in adcanve,
 
Cheers, Tobias
<div>

  <div>
   Hi folks,
  </div> 
  <div>
   &nbsp;
  </div> 
  <div>
   your projects look outstanding and I would love to dig into it a little bit more.
  </div> 
  <div>
   &nbsp;
  </div> 
  <div>
   Unfort. I cannot open the Eagle files of your board-m1 files. May I ask you if you can send me&nbsp; or release the pdf version as well. I'm interested how you connected the DVI to the FPGA.
  </div> 
  <div>
   &nbsp;
  </div> 
  <div>
   Thanks a lot in adcanve,
  </div> 
  <div>
   &nbsp;
  </div> 
  <div>
   Cheers, Tobias
  </div>

</div>
Florent Kermarrec | 31 Oct 15:23 2014
Picon

[M-Labs devel] New Ethernet MAC for MiSoC

Hi,

I've been working on a new Ethernet MAC for MiSoC to replace Minimac3 and
to be more generic (support for various PHYs and user interfaces).

For this new Ethernet MAC, I have added packet support for dataflow in Migen
and added a couples of modules to ease use of dataflow:
- Converter allows easy conversion of data_width for dataflow.
(ex here: Wishbone SRAM reader (32-bits) --> PHY (8-bits))
- Pipeline is a simple module to connect together modules of the dataflow.
DataFlowGraph already allows this, but is more difficult to use and does not
allow use of modules with AutoCSR.

PHYS:
For now, this EthMAC includes MII(10/100Mbps) and GMII(1Gbps) PHYs.
A Loopback PHY is also provided for testing purpose (simulation or
debugging software/gateware)

User Interface:
For now this EthMAC provides Wishbone interface and is also able to
expose dataflow to the user. (In case we want to have a HW UDP/IP for
example). It will be easy in the future to add LASMI interface to it.

Tests:
This EthMac has been validated on the KC705 with GMII with MiniSoC.
(LM32 <at> 125MHz / DDR3 / GbEthernet)
Since I don't have my Mixxeo board with me, I've not been able to test
it on it, but I already tested the PHY on it, so it should work. (In
case someone want to do the test on Milkymist or Mixxeo? :))
Simulation are also available in misoclib/ethmac/test/

Logic:
Logic usage should be very similar to Minimac3 when disabling HW CRC
and Preamble. (Note that Minimac3 has 2 RX slots, 1 TX slot, here
we can configure it and by default it's: 2 RX slots / 2 TX slots).
Adding a second TX slot greatly increases performance (>40%).

Implementation on KC705 still takes lots of time, so I mainly used
ISE. (LM32 LSU is not correctly implemented with Vivado, I'm in contact
with a Xilinx FAE to try to understand that...)

SRAM_READER use FullMemoryWE for it's memory. (Xilinx does not support
byte enable on Dual port RAM). This is maybe something we will have to clean
up.

Patches:
Since the patches are larges, you can find them here:

I've tried to split Migen patches, but the MiSoC patch for the EthMAC
is really large, sorry for the review...

In case you would have done things in a different way, I'm of course OK
to discuss of that.

Regards,

Florent.
<div><div dir="ltr">
<div>Hi,</div>
<div><br></div>
<div>I've been working on a new Ethernet MAC for MiSoC to replace Minimac3 and</div>
<div>to be more generic (support for various PHYs and user interfaces).</div>
<div><br></div>
<div>For this new Ethernet MAC, I have added packet support for dataflow in Migen</div>
<div>and added a couples of modules to ease use of dataflow:</div>
<div>- Converter allows easy conversion of data_width for dataflow.</div>
<div>(ex here: Wishbone SRAM reader (32-bits) --&gt; PHY (8-bits))</div>
<div>- Pipeline is a simple module to connect together modules of the dataflow.</div>
<div>DataFlowGraph already allows this, but is more difficult to use and does not</div>
<div>allow use of modules with AutoCSR.</div>
<div><br></div>
<div>PHYS:</div>
<div>For now, this EthMAC includes MII(10/100Mbps) and GMII(1Gbps) PHYs.</div>
<div>A Loopback PHY is also provided for testing purpose (simulation or</div>
<div>debugging software/gateware)</div>
<div><br></div>
<div>User Interface:</div>
<div>For now this EthMAC provides Wishbone interface and is also able to</div>
<div>expose dataflow to the user. (In case we want to have a HW UDP/IP for</div>
<div>example). It will be easy in the future to add LASMI interface to it.</div>
<div><br></div>
<div>Tests:</div>
<div>This EthMac has been validated on the KC705 with GMII with MiniSoC.</div>
<div>(LM32  <at>  125MHz / DDR3 / GbEthernet)</div>
<div>Since I don't have my Mixxeo board with me, I've not been able to test</div>
<div>it on it, but I already tested the PHY on it, so it should work. (In</div>
<div>case someone want to do the test on Milkymist or Mixxeo? :))</div>
<div>Simulation are also available in misoclib/ethmac/test/≤/div>
<div><br></div>
<div>Logic:</div>
<div>Logic usage should be very similar to Minimac3 when disabling HW CRC</div>
<div>and Preamble. (Note that Minimac3 has 2 RX slots, 1 TX slot, here</div>
<div>we can configure it and by default it's: 2 RX slots / 2 TX slots).</div>
<div>Adding a second TX slot greatly increases performance (&gt;40%).</div>
<div><br></div>
<div>Implementation on KC705 still takes lots of time, so I mainly used</div>
<div>ISE. (LM32 LSU is not correctly implemented with Vivado, I'm in contact</div>
<div>with a Xilinx FAE to try to understand that...)</div>
<div><br></div>
<div>SRAM_READER use&nbsp;FullMemoryWE for it's memory. (Xilinx does not support</div>
<div>byte enable on Dual port RAM). This is maybe something we will have to clean</div>
<div>up.</div>
<div><br></div>
<div>Patches:</div>
<div>Since the patches are larges, you can find them here:</div>
<div><a href="http://enjoy-digital.fr/open-hardware/3/migen_ethmac_patches.7z">enjoy-digital.fr/open-hardware/3/migen_ethmac_patches.7z</a></div>
<div><a href="http://enjoy-digital.fr/open-hardware/3/misoc_ethmac_patches.7z">enjoy-digital.fr/open-hardware/3/misoc_ethmac_patches.7z</a></div>
<div><br></div>
<div>I've tried to split Migen patches, but the MiSoC patch for the EthMAC</div>
<div>is really large, sorry for the review...</div>
<div><br></div>
<div>In case you would have done things in a different way, I'm of course OK</div>
<div>to discuss of that.</div>
<div><br></div>
<div>Regards,</div>
<div><br></div>
<div>Florent.</div>
</div></div>

Gmane