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>
Sébastien Bourdeauducq | 30 Oct 15:47 2014
Picon

[M-Labs devel] ARTIQ

Hi,

this is probably old news if you are on #m-labs IRC, but I've been
working (with help from Florent and Yann) on developing a new quantum
physics experiment control system for the Ion Storage Group at NIST.

It uses MiSoC with custom realtime I/O gateware and a Python static
compiler to provide both high expressivity and good timing performance.

This slideshow makes a good intro:
http://m-labs.hk/artiq/slides_taaccs.pdf

It's an open source project, and you are welcome to subscribe to the
mailing list to follow and participate in the discussions:
https://ssl.serverraum.org/lists/listinfo/artiq

Sébastien
_______________________________________________
M-Labs devel mailing list
https://ssl.serverraum.org/lists/listinfo/devel
Sébastien Bourdeauducq | 11 Oct 17:16 2014
Picon

[M-Labs devel] Fwd: [EHSM-public] FOSDEM 2015 EDA Devroom Call for Participation


---------- Forwarded message ----------
From: *Javier Serrano* <javier.serrano.pareja@...
<mailto:javier.serrano.pareja@...>>
Date: 11 October 2014 09:59
Subject: [Kicad-developers] FOSDEM 2015 EDA Devroom Call for Participation
To: KiCad Developers <kicad-developers@...
<mailto:kicad-developers@...>>

Dear all,

Here's the Call for Participation for the FOSS EDA Devroom in FOSDEM 2015:

http://www.ohwr.org/projects/ohr-meta/wiki/FOSDEM2015

Looking forward to meeting many of you there.

Javier

Guy Hutchison | 25 Sep 02:30 2014
Picon

[M-Labs devel] ECC generator/checker

Hamming code ECC generator/checker for SECDEC code.


<div><div dir="ltr">Hamming code ECC generator/checker for SECDEC code.<div><br></div>
<div><br></div>
</div></div>
Florent Kermarrec | 24 Sep 22:41 2014
Picon

[M-Labs devel] [PATCH] add generic CRCEngine, CRC32, CRCInserter and CRCChecker


<div><div dir="ltr"><br></div></div>

Gmane