Skip to content

Commit e69e27a

Browse files
committed
jenkins hash/map
1 parent ee89e9e commit e69e27a

14 files changed

Lines changed: 1075 additions & 3 deletions

‎Makefile‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
iverilog -o $@ $^
88

99
# tagets
10-
default: bin/opcap.lxt bin/obin2bcd8.lxt bin/obin2bcdN.lxt
10+
default: bin/opcap.lxt bin/obin2bcd8.lxt bin/obin2bcdN.lxt bin/ohash.lxt bin/ohashmap.lxt
1111
clean:
1212
RM bin/*
1313

@@ -25,3 +25,11 @@ bin/obin2bcd8.bin: bcd/bin2bcd8*.v bcd/add3.v
2525
bin/obin2bcdN.lxt: bin/obin2bcdN.bin
2626
bin/obin2bcdN.bin: bcd/bin2bcdN*.v
2727
iverilog -o $@ $^
28+
29+
bin/ohash.lxt: bin/ohash.bin
30+
bin/ohash.bin: hash/jenkins*.v
31+
iverilog -o $@ $^
32+
33+
bin/ohashmap.lxt: bin/ohashmap.bin
34+
bin/ohashmap.bin: hash/serialMap*.v hash/jenkins.v
35+
iverilog -o $@ $^

‎README.markdown‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ bcd
99
---
1010
Convertors to and from binary to numerical ascii/bcd
1111

12+
hash
13+
----
14+
jenins.v - a framed byte-wise Jenkins hash-code calculator
15+
serialMap.v - a key-to-value map data structure. Implemented using a l
16+
inear probe looked seeded by the key's hash. Module parameterised by k/v sizes.
1217

1318
testbench
1419
---------
1520
Test benches can be rebuilt with $ make
1621
Simulation waveforms are written to lxt2 format and are opened with gtkwave when a bench or implementation changes. gtkwave 'save' files (gtksav/*.sav) are included that setup zoom and add appropriate signals.
17-
18-

‎gtksav/obin2bcd8.sav‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[*]
2+
[*] GTKWave Analyzer v3.3.31 (w)1999-2012 BSI
3+
[*] Sat Mar 24 13:04:25 2012
4+
[*]
5+
[dumpfile] "/Users/shuckc/Documents/verilog-utils/bin/obin2bcd8.lxt"
6+
[dumpfile_mtime] "Sat Mar 24 12:57:44 2012"
7+
[dumpfile_size] 1781
8+
[savefile] "/Users/shuckc/Documents/verilog-utils/gtksav/obin2bcd8.sav"
9+
[timestart] 0
10+
[size] 1000 600
11+
[pos] 34 140
12+
*-18.622717 8730000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
13+
[treeopen] bin2bcd8_test.
14+
[treeopen] bin2bcd8_test.uut.
15+
[sst_width] 211
16+
[signals_width] 134
17+
[sst_expanded] 1
18+
[sst_vpaned_height] 154
19+
@22
20+
bin2bcd8_test.uut.A[7:0]
21+
@200
22+
-output
23+
@24
24+
bin2bcd8_test.uut.HUNDREDS[1:0]
25+
bin2bcd8_test.uut.TENS[3:0]
26+
@25
27+
bin2bcd8_test.uut.ONES[3:0]
28+
[pattern_trace] 1
29+
[pattern_trace] 0

‎gtksav/ohash.sav‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[timestart] 0
2+
[size] 1719 839
3+
[pos] 2066 115
4+
*-17.572342 560000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
5+
[treeopen] jenkins_test.
6+
@28
7+
jenkins_test.uut.CLOCK[0]
8+
@200
9+
-public
10+
@28
11+
jenkins_test.uut.sample[0]
12+
@820
13+
jenkins_test.uut.value[7:0]
14+
@28
15+
jenkins_test.uut.complete[0]
16+
@22
17+
jenkins_test.uut.hash[31:0]
18+
@200
19+
-internals
20+
@22
21+
jenkins_test.uut.value[7:0]
22+
jenkins_test.uut.work[31:0]
23+
jenkins_test.uut.hash[31:0]
24+
@28
25+
jenkins_test.uut.sample[0]
26+
jenkins_test.uut.started[0]
27+
jenkins_test.uut.complete_int[0]
28+
[pattern_trace] 1
29+
[pattern_trace] 0

‎gtksav/ohashmap.sav‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[timestart] 0
2+
[size] 1719 839
3+
[pos] 2066 115
4+
*-17.572342 560000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
5+
[treeopen] serialMap_test.
6+
[treeopen] serialMap_test.uut.
7+
@200
8+
-HASHMAP
9+
@28
10+
serialMap_test.uut.query[0]
11+
@820
12+
serialMap_test.uut.key[7:0]
13+
@28
14+
serialMap_test.uut.notfound[0]
15+
serialMap_test.uut.found[0]
16+
@22
17+
serialMap_test.uut.data[7:0]
18+
@201
19+
-internals
20+
@22
21+
serialMap_test.uut.key[7:0]
22+
@24
23+
serialMap_test.uut.keycount[7:0]
24+
@28
25+
serialMap_test.uut.hashcomplete[0]
26+
@22
27+
serialMap_test.uut.state[3:0]
28+
serialMap_test.uut.base[5:0]
29+
serialMap_test.uut.pos[5:0]
30+
@24
31+
serialMap_test.uut.chkchar[7:0]
32+
serialMap_test.uut.address[32:0]
33+
@22
34+
serialMap_test.uut.memd[7:0]
35+
@820
36+
serialMap_test.uut.memd[7:0]
37+
@28
38+
serialMap_test.uut.keyCharNull[0]
39+
serialMap_test.uut.posempty[0]
40+
serialMap_test.uut.entryEnd[0]
41+
@22
42+
serialMap_test.uut.data[7:0]
43+
[pattern_trace] 1
44+
[pattern_trace] 0

‎hash/build.sh‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash -e
2+
gcc -o jenkins.o jenkins.c
3+
./jenkins.o > jenkins.csv
4+
diff jenkins.csv jenkins.knowngood
5+

‎hash/jenkins.c‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Jenkins hash test bench
2+
//
3+
#include <stdio.h>
4+
#include <stdint.h>
5+
#include <string.h>
6+
7+
uint32_t jenkins_one_at_a_time_hash(char *key, size_t len) {
8+
uint32_t hash = 0;
9+
uint32_t i;
10+
for(i = 0; i < len; ++i) {
11+
hash += key[i];
12+
hash += (hash << 10);
13+
hash ^= (hash >> 6);
14+
}
15+
hash += (hash << 3);
16+
hash ^= (hash >> 11);
17+
hash += (hash << 15);
18+
return hash;
19+
}
20+
21+
22+
int main(void) {
23+
printf("value,len,hash\n");
24+
char *values[] = {"VOD.L", "hello", "plane", "A", "B", "C", "A", "a", "BT.L", "ARM.L", NULL};
25+
char **i = values;
26+
while (*i) {
27+
size_t len = strlen(*i);
28+
printf("%d,%x,%s\n", len, jenkins_one_at_a_time_hash(*i, len), *i);
29+
i++;
30+
}
31+
return 0;
32+
}
33+

‎hash/jenkins.csv‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
value,len,hash
2+
5,ef143afd,VOD.L
3+
5,c8fd181b,hello
4+
5,198530f1,plane
5+
1,820103f0,A
6+
1,b7346e56,B
7+
1,a69ecd2b,C
8+
1,820103f0,A
9+
1,ca2e9442,a
10+
4,cc098a96,BT.L
11+
5,bc530b1e,ARM.L

‎hash/jenkins.knowngood‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
value,len,hash
2+
VOD.L,5,ef143afd
3+
hello,5,c8fd181b
4+
plane,5,198530f1
5+
A,1,820103f0
6+
B,1,b7346e56
7+
C,1,a69ecd2b
8+
A,1,820103f0
9+
a,1,ca2e9442
10+
BT.L,4,cc098a96
11+
ARM.L,5,bc530b1e

‎hash/jenkins.v‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
`timescale 1ns / 1ps
2+
//////////////////////////////////////////////////////////////////////////////////
3+
// Engineer: Chris Shucksmith
4+
// Create Date: 10:06:51 04/04/2011
5+
// Design Name:
6+
// Module Name: jenkins
7+
// Project Name:
8+
// Jenkins hash generator based on http://en.wikipedia.org/wiki/Jenkins_hash_function
9+
// originally proposed by Bob Jenkins here http://www.burtleburtle.net/bob/hash/doobs.html - not the
10+
// hash proposed in the text, but a simplification for single bytes.
11+
//
12+
// Additional Comments:
13+
// uint32_t jenkins_one_at_a_time_hash(char *key, size_t len) {
14+
// uint32_t hash = 0;
15+
// uint32_t i;
16+
// for(i = 0; i < len; ++i) {
17+
// hash += key[i];
18+
// hash += (hash << 10);
19+
// hash ^= (hash >> 6);
20+
// }
21+
// hash += (hash << 3);
22+
// hash ^= (hash >> 11);
23+
// hash += (hash << 15);
24+
// return hash;
25+
// }
26+
//
27+
//
28+
//////////////////////////////////////////////////////////////////////////////////
29+
module jenkins(
30+
input CLOCK,
31+
input sample,
32+
input [7:0] value,
33+
output [31:0] hash,
34+
output complete
35+
);
36+
37+
reg [31:0] work = 0;
38+
reg [31:0] out = 0;
39+
reg started = 0;
40+
reg complete_int = 0;
41+
42+
// per-byte calculations (combinatorial)
43+
wire [31:0] c1 = work + value;
44+
wire [31:0] c2 = c1 + (c1 << 10);
45+
wire [31:0] c3 = c2 ^ (c2 >> 6);
46+
// post-processing output stage (combinatorial)
47+
wire [31:0] o1 = work + (work << 3);
48+
wire [31:0] o2 = o1 ^ (o1 >> 11);
49+
wire [31:0] o3 = o2 + (o2 << 15);
50+
51+
52+
always @(posedge CLOCK) begin
53+
if (sample) begin
54+
work <= c3;
55+
started <= 1;
56+
complete_int <= 0;
57+
end else if (started && !sample) begin
58+
started <= 0;
59+
complete_int <= 1;
60+
end else if (!started) begin
61+
complete_int <= 0;
62+
work <= 0;
63+
started <= 0;
64+
complete_int <= 0;
65+
end
66+
out <= o3;
67+
68+
end
69+
70+
assign hash = out;
71+
assign complete = complete_int;
72+
73+
endmodule

0 commit comments

Comments
 (0)