Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #959 > unrolled thread
| Started by | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| First post | 2011-04-02 19:36 +0100 |
| Last post | 2011-04-11 20:16 +0100 |
| Articles | 15 — 3 participants |
Back to article view | Back to comp.lang.forth
Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-02 19:36 +0100
Re: Verilog macro issue Jan Coombs <jan_2011-02@murray-microft.co.uk> - 2011-04-02 20:26 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-02 20:31 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-02 20:43 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-02 21:36 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-02 22:12 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-02 23:01 +0100
Re: Verilog macro issue Jan Coombs <jan_2011-02@murray-microft.co.uk> - 2011-04-02 23:33 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-03 03:58 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-03 12:27 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-03 13:20 +0100
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-07 23:26 +0100
Re: Verilog macro issue Jan Coombs <jan_2011-02@murray-microft.co.uk> - 2011-04-10 23:20 +0100
Re: Verilog macro issue rickman <gnuarm@gmail.com> - 2011-04-11 10:36 -0700
Re: Verilog macro issue Chris Hinsley <chris.hinsley@gmail.com> - 2011-04-11 20:16 +0100
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-02 19:36 +0100 |
| Subject | Verilog macro issue |
| Message-ID | <2011040219361212758-chrishinsley@gmailcom> |
Hi folks, I've been a bit quiet recontly, mostly because I've been heads down on learning Verilog and moving my CPU from Logisym over to it. I have a question that you Forth Verilog guys might be able to help with. I have some encoders done like the folowing: module enc4(i, o); input [15:0] i; output [3:0] o; reg [3:0] o; always @(i) begin o = 4'h0; case(i) 16'b0000000000000010: o = 4'h1; 16'b0000000000000100: o = 4'h2; 16'b0000000000001000: o = 4'h3; 16'b0000000000010000: o = 4'h4; 16'b0000000000100000: o = 4'h5; 16'b0000000001000000: o = 4'h6; 16'b0000000010000000: o = 4'h7; 16'b0000000100000000: o = 4'h8; 16'b0000001000000000: o = 4'h9; 16'b0000010000000000: o = 4'hA; 16'b0000100000000000: o = 4'hB; 16'b0001000000000000: o = 4'hC; 16'b0010000000000000: o = 4'hD; 16'b0100000000000000: o = 4'hE; 16'b1000000000000000: o = 4'hF; endcase end endmodule But that's all getting a bit long winded, so I thought I'd do a macro to generate any width encoder. But I've hit a problem with the generate variable comparison needing to be a constant (that's the FPGA compiler error). Here's the code I wanted to write. Any advice for how to achieve this macro ? `define ENCODER(NAME, BITS) \ module NAME(i, o); \ input [((2 ** BITS) - 1):0] i; \ output [(BITS - 1):0] o; \ genvar n; \ generate \ for (n = 0; n < (2 ** BITS); n = n + 1) \ begin \ if (i == (2 ** n)) \ assign o = n; \ end \ endgenerate \ endmodule `ENCODER(enc1, 1) `ENCODER(enc2, 2) `ENCODER(enc3, 3) Chears. Chris
[toc] | [next] | [standalone]
| From | Jan Coombs <jan_2011-02@murray-microft.co.uk> |
|---|---|
| Date | 2011-04-02 20:26 +0100 |
| Message-ID | <EbGdnVLa4s_15QrQnZ2dnUVZ8mCdnZ2d@brightview.co.uk> |
| In reply to | #959 |
On 02/04/11 19:36, Chris Hinsley wrote: > Hi folks, I've been a bit quiet recontly, mostly because I've been > heads down on learning Verilog and moving my CPU from Logisym over > to it. > > I have a question that you Forth Verilog guys might be able to help > with. > > I have some encoders done like the folowing: > > module enc4(i, o); > input [15:0] i; > output [3:0] o; > reg [3:0] o; > always @(i) > begin > o = 4'h0; > case(i) > 16'b0000000000000010: o = 4'h1; > 16'b0000000000000100: o = 4'h2; > 16'b0000000000001000: o = 4'h3; > 16'b0000000000010000: o = 4'h4; > 16'b0000000000100000: o = 4'h5; > 16'b0000000001000000: o = 4'h6; > 16'b0000000010000000: o = 4'h7; > 16'b0000000100000000: o = 4'h8; > 16'b0000001000000000: o = 4'h9; > 16'b0000010000000000: o = 4'hA; > 16'b0000100000000000: o = 4'hB; > 16'b0001000000000000: o = 4'hC; > 16'b0010000000000000: o = 4'hD; > 16'b0100000000000000: o = 4'hE; > 16'b1000000000000000: o = 4'hF; > endcase > end > endmodule This one is a priority encoder, so the case statement is unnecessarily complex. For this, write loops to perform something like this: o[3] = i[15]|i[14]|i[13]|i[12]|i[11]|i[10]|i[9]|i[8] o[2] = i[15:]|i[14]|i[13]|i[12]|i[7]|i[6]|i[5]|i[4] o[1] = i[15]|i[14]|i[11]|i[10]|i[7]|i[6]|i[3]|i[2] o[0] = i[15]|i[13]|i[11]|i[9]|i[7]|i[5]|i[3]|i[1] If you'd like to interactively test as you develop, consider using MyHDL (myhdl.org), and then export your working code as Verilog or VHDL. Jan Coombs
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-02 20:31 +0100 |
| Message-ID | <2011040220310050490-chrishinsley@gmailcom> |
| In reply to | #960 |
On 2011-04-02 20:26:32 +0100, Jan Coombs said: > On 02/04/11 19:36, Chris Hinsley wrote: >> Hi folks, I've been a bit quiet recontly, mostly because I've been >> heads down on learning Verilog and moving my CPU from Logisym over >> to it. >> >> I have a question that you Forth Verilog guys might be able to help >> with. >> >> I have some encoders done like the folowing: >> >> module enc4(i, o); >> input [15:0] i; >> output [3:0] o; >> reg [3:0] o; >> always @(i) >> begin >> o = 4'h0; >> case(i) >> 16'b0000000000000010: o = 4'h1; >> 16'b0000000000000100: o = 4'h2; >> 16'b0000000000001000: o = 4'h3; >> 16'b0000000000010000: o = 4'h4; >> 16'b0000000000100000: o = 4'h5; >> 16'b0000000001000000: o = 4'h6; >> 16'b0000000010000000: o = 4'h7; >> 16'b0000000100000000: o = 4'h8; >> 16'b0000001000000000: o = 4'h9; >> 16'b0000010000000000: o = 4'hA; >> 16'b0000100000000000: o = 4'hB; >> 16'b0001000000000000: o = 4'hC; >> 16'b0010000000000000: o = 4'hD; >> 16'b0100000000000000: o = 4'hE; >> 16'b1000000000000000: o = 4'hF; >> endcase >> end >> endmodule > > This one is a priority encoder, so the case statement is unnecessarily > complex. For this, write loops to perform something like this: > > o[3] = i[15]|i[14]|i[13]|i[12]|i[11]|i[10]|i[9]|i[8] > o[2] = i[15:]|i[14]|i[13]|i[12]|i[7]|i[6]|i[5]|i[4] > o[1] = i[15]|i[14]|i[11]|i[10]|i[7]|i[6]|i[3]|i[2] > o[0] = i[15]|i[13]|i[11]|i[9]|i[7]|i[5]|i[3]|i[1] > > > If you'd like to interactively test as you develop, consider using > MyHDL (myhdl.org), and then export your working code as Verilog or VHDL. > > Jan Coombs I didn't think it was a priority encoder ! Are you sure ? I thought this was a priority encoder ? module pri_enc3(i, o); input [7:0] i; output [2:0] o; reg [2:0] o; always @(i) begin casez(i) 8'b1???????: o = 3'h7; 8'b01??????: o = 3'h6; 8'b001?????: o = 3'h5; 8'b0001????: o = 3'h4; 8'b00001???: o = 3'h3; 8'b000001??: o = 3'h2; 8'b0000001?: o = 3'h1; 8'b00000001: o = 3'h0; endcase end endmodule This uses a casez, and has don't care bits specfied. ? Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-02 20:43 +0100 |
| Message-ID | <2011040220435062162-chrishinsley@gmailcom> |
| In reply to | #961 |
> I didn't think it was a priority encoder ! Are you sure ? I thought > this was a priority encoder ? Just checked on the Simulator, and it's definately _not_ a priority encoder. It's an encoder with 0 as the output in any error case. ! So back to my original question. How to write the encoder generating macro. :) Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-02 21:36 +0100 |
| Message-ID | <2011040221362339753-chrishinsley@gmailcom> |
| In reply to | #963 |
On 2011-04-02 20:43:50 +0100, Chris Hinsley said: >> >> I didn't think it was a priority encoder ! Are you sure ? I thought >> this was a priority encoder ? > > Just checked on the Simulator, and it's definately _not_ a priority > encoder. It's an encoder with 0 as the output in any error case. ! > > So back to my original question. How to write the encoder generating macro. :) > > Chris This works as a macro to define priority encoders, but still not the same as the original encoder done with a case. `define PRI_ENCODER(NAME, BITS) \ module NAME(i, o); \ input [((2 ** BITS) - 1):0] i; \ output [(BITS - 1):0] o; \ reg [(BITS - 1):0] o; \ integer n; \ always @(i) \ begin : THE_LOOP \ o = BITS'b0; \ for (n = 0; n < (2 ** BITS); n = n + 1) \ begin \ if (i[n]) \ begin \ o = n; \ disable THE_LOOP; \ end \ end \ end \ endmodule `PRI_ENCODER(pri_enc3, 3) `PRI_ENCODER(pri_enc4, 4) `PRI_ENCODER(pri_enc5, 5)
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-02 22:12 +0100 |
| Message-ID | <2011040222124192049-chrishinsley@gmailcom> |
| In reply to | #964 |
On 2011-04-02 21:36:23 +0100, Chris Hinsley said: > This works as a macro to define priority encoders, but still not the > same as the original encoder done with a case. > > `define PRI_ENCODER(NAME, BITS) \ > module NAME(i, o); \ > input [((2 ** BITS) - 1):0] i; \ > output [(BITS - 1):0] o; \ > reg [(BITS - 1):0] o; \ > integer n; \ > always @(i) \ > begin : THE_LOOP \ > o = BITS'b0; \ > for (n = 0; n < (2 ** BITS); n = n + 1) \ > begin \ > if (i[n]) \ > begin \ > o = n; \ > disable THE_LOOP; \ > end \ > end \ > end \ > endmodule > > `PRI_ENCODER(pri_enc3, 3) > `PRI_ENCODER(pri_enc4, 4) > `PRI_ENCODER(pri_enc5, 5) I've ended up with this, which does the correct job, but I really think the code sucks. There has to be a better way to do it than this ! God knows what the FPGA compiler will produce for this. :( `define ENCODER(NAME, BITS) \ module NAME(i, o); \ input [((2 ** BITS) - 1):0] i; \ output [(BITS - 1):0] o; \ reg [(BITS - 1):0] o; \ integer n, f; \ always @(i) \ begin : THE_LOOP \ o = BITS'b0; \ f = 0; \ for (n = 0; n < (2 ** BITS); n = n + 1) \ begin \ if (i[n]) \ begin \ if (f) disable THE_LOOP; \ f = 1; \ end \ end \ for (n = 0; n < (2 ** BITS); n = n + 1) \ begin \ if (i[n]) \ begin \ o = n; \ disable THE_LOOP; \ end \ end \ end \ endmodule `ENCODER(enc1, 1) `ENCODER(enc2, 2) `ENCODER(enc3, 3) `ENCODER(enc4, 4) `ENCODER(enc5, 5)
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-02 23:01 +0100 |
| Message-ID | <2011040223012056408-chrishinsley@gmailcom> |
| In reply to | #960 |
> o[3] = i[15]|i[14]|i[13]|i[12]|i[11]|i[10]|i[9]|i[8] > o[2] = i[15:]|i[14]|i[13]|i[12]|i[7]|i[6]|i[5]|i[4] > o[1] = i[15]|i[14]|i[11]|i[10]|i[7]|i[6]|i[3]|i[2] > o[0] = i[15]|i[13]|i[11]|i[9]|i[7]|i[5]|i[3]|i[1] Jan, it took me a while for this to sink in. :) I went back to my Logisim schematic for the encoder and I do exactly this. ! What a berk, I didn't even look at it when I tried to come up with the Verilog version. Idiot ! <slaps head> Chris
[toc] | [prev] | [next] | [standalone]
| From | Jan Coombs <jan_2011-02@murray-microft.co.uk> |
|---|---|
| Date | 2011-04-02 23:33 +0100 |
| Message-ID | <5dGdnYypo8bZOQrQnZ2dnUVZ8s2dnZ2d@brightview.co.uk> |
| In reply to | #968 |
On 02/04/11 23:01, Chris Hinsley wrote: >> o[3] = i[15]|i[14]|i[13]|i[12]|i[11]|i[10]|i[9]|i[8] >> o[2] = i[15:]|i[14]|i[13]|i[12]|i[7]|i[6]|i[5]|i[4] >> o[1] = i[15]|i[14]|i[11]|i[10]|i[7]|i[6]|i[3]|i[2] >> o[0] = i[15]|i[13]|i[11]|i[9]|i[7]|i[5]|i[3]|i[1] > > Jan, it took me a while for this to sink in. :) Well, I've read your Verilog a few times, without the lights coming on, so you still got there first. And sorry to have short-changed you, it was only half of a slow priority encoder. Jan Coombs
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-03 03:58 +0100 |
| Message-ID | <2011040303581035956-chrishinsley@gmailcom> |
| In reply to | #971 |
On 2011-04-02 23:33:40 +0100, Jan Coombs said: > On 02/04/11 23:01, Chris Hinsley wrote: >>> o[3] = i[15]|i[14]|i[13]|i[12]|i[11]|i[10]|i[9]|i[8] >>> o[2] = i[15:]|i[14]|i[13]|i[12]|i[7]|i[6]|i[5]|i[4] >>> o[1] = i[15]|i[14]|i[11]|i[10]|i[7]|i[6]|i[3]|i[2] >>> o[0] = i[15]|i[13]|i[11]|i[9]|i[7]|i[5]|i[3]|i[1] >> >> Jan, it took me a while for this to sink in. :) > > Well, I've read your Verilog a few times, without the lights coming on, > so you still got there first. > > And sorry to have short-changed you, it was only half of a slow > priority encoder. > > Jan Coombs module enc5(i, o); input [31:0] i; output [4:0] o; assign o[0] = |i[01:01] | |i[03:03] | |i[05:05] | |i[07:07] | |i[09:09] | |i[11:11] | |i[13:13] | |i[15:15] | |i[17:17] | |i[19:19] | |i[21:21] | |i[23:23] | |i[25:25] | |i[27:27] | |i[29:29] | |i[31:31]; assign o[1] = |i[03:02] | |i[07:06] | |i[11:10] | |i[15:14] | |i[19:18] | |i[23:22] | |i[27:26] | |i[31:30]; assign o[2] = |i[07:04] | |i[15:12] | |i[23:20] | |i[31|28]; assign o[3] = |i[15:08] | |i[31:24]; assign o[4] = |i[31:16]; endmodule This produces a nicely efficient gate version on the FPGA. But I'm still have real problem getting this idea expressed as a macro that will let me generate any width encoder. It's late I'm off to bed and see if any Verilog gurus will give it a go while I'm in the land of nod. :) Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-03 12:27 +0100 |
| Message-ID | <2011040312274643418-chrishinsley@gmailcom> |
| In reply to | #977 |
> module enc5(i, o); > input [31:0] i; > output [4:0] o; > assign o[0] = |i[01:01] | |i[03:03] | |i[05:05] | |i[07:07] | > |i[09:09] | |i[11:11] | |i[13:13] | |i[15:15] | |i[17:17] | |i[19:19] | > |i[21:21] | |i[23:23] | |i[25:25] | |i[27:27] | |i[29:29] | |i[31:31]; > assign o[1] = |i[03:02] | |i[07:06] | |i[11:10] | |i[15:14] | > |i[19:18] | |i[23:22] | |i[27:26] | |i[31:30]; > assign o[2] = |i[07:04] | |i[15:12] | |i[23:20] | |i[31|28]; > assign o[3] = |i[15:08] | |i[31:24]; > assign o[4] = |i[31:16]; > endmodule > > This produces a nicely efficient gate version on the FPGA. But I'm > still have real problem getting this idea expressed as a macro that > will let me generate any width encoder. > > It's late I'm off to bed and see if any Verilog gurus will give it a go > while I'm in the land of nod. :) > > Chris OK, some progress here, but I'd really like to role one macro that could work out and assign the row 'reg' declarations. I'm not sure how I can get that to happen. But at least this code dosn't require me to remember and manually or all the bit patterns together, plus it compiles to nice wide or gates. `define ENC_ROW(REG, BIT, WIDTH) \ always \ begin \ integer s; \ integer r; \ REG = 0; \ for (s = (2 ** BIT); s < WIDTH; s = s + (2 ** BIT) + (2 ** BIT)) \ begin \ for (r = s; r < (s + (2 ** BIT)); r = r + 1) \ begin \ REG = (REG | i[r]); \ end \ end \ end \ assign o[BIT] = REG; module enc1(i, o); parameter BITS = 1; parameter WIDTH = (2 ** BITS); input [(WIDTH - 1):0] i; output [(BITS - 1):0] o; reg a; `ENC_ROW(a, 0, WIDTH) endmodule module enc2(i, o); parameter BITS = 2; parameter WIDTH = (2 ** BITS); input [(WIDTH - 1):0] i; output [(BITS - 1):0] o; reg a, b; `ENC_ROW(a, 0, WIDTH) `ENC_ROW(b, 1, WIDTH) endmodule module enc3(i, o); parameter BITS = 3; parameter WIDTH = (2 ** BITS); input [(WIDTH - 1):0] i; output [(BITS - 1):0] o; reg a, b, c; `ENC_ROW(a, 0, WIDTH) `ENC_ROW(b, 1, WIDTH) `ENC_ROW(c, 2, WIDTH) endmodule module enc4(i, o); parameter BITS = 4; parameter WIDTH = (2 ** BITS); input [(WIDTH - 1):0] i; output [(BITS - 1):0] o; reg a, b, c, d; `ENC_ROW(a, 0, WIDTH) `ENC_ROW(b, 1, WIDTH) `ENC_ROW(c, 2, WIDTH) `ENC_ROW(d, 3, WIDTH) endmodule module enc5(i, o); parameter BITS = 5; parameter WIDTH = (2 ** BITS); input [(WIDTH - 1):0] i; output [(BITS - 1):0] o; reg a, b, c, d, e; `ENC_ROW(a, 0, WIDTH) `ENC_ROW(b, 1, WIDTH) `ENC_ROW(c, 2, WIDTH) `ENC_ROW(d, 3, WIDTH) `ENC_ROW(e, 4, WIDTH) endmodule
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-03 13:20 +0100 |
| Message-ID | <2011040313203492550-chrishinsley@gmailcom> |
| In reply to | #986 |
Hurrah, finally, I managed it. Gee that was tough but educational. ! Thanks Jan for putting me on the path. :) `define ENCODER(NAME, BITS) \ module NAME(i, o); \ parameter WIDTH = (2 ** BITS); \ input [(WIDTH - 1):0] i; \ output [(BITS - 1):0] o; \ reg [(BITS - 1):0] r; \ genvar row; \ generate \ begin \ for (row = 0; row < BITS; row = row + 1) \ begin : G \ always \ begin \ integer start; \ integer range; \ r[row] = 0; \ for (start = (2 ** row); start < WIDTH; start = start + (2 ** row) + (2 ** row)) \ begin \ for (range = start; range < (start + (2 ** row)); range = range + 1) \ begin \ r[row] = (r[row] | i[range]); \ end \ end \ end \ assign o[row] = r[row]; \ end \ end \ endgenerate \ endmodule `ENCODER(enc1, 1) `ENCODER(enc2, 2) `ENCODER(enc3, 3) `ENCODER(enc4, 4) `ENCODER(enc5, 5)
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-07 23:26 +0100 |
| Message-ID | <2011040723265536787-chrishinsley@gmailcom> |
| In reply to | #987 |
On 2011-04-03 13:20:34 +0100, Chris Hinsley said: > Hurrah, finally, I managed it. Gee that was tough but educational. ! > > Thanks Jan for putting me on the path. :) > > `define ENCODER(NAME, BITS) \ > module NAME(i, o); \ > parameter WIDTH = (2 ** BITS); \ > input [(WIDTH - 1):0] i; \ > output [(BITS - 1):0] o; \ > reg [(BITS - 1):0] r; \ > genvar row; \ > generate \ > begin \ > for (row = 0; row < BITS; row = row + 1) \ > begin : G \ > always \ > begin \ > integer start; \ > integer range; \ > r[row] = 0; \ > for (start = (2 ** row); start < WIDTH; start = start + (2 ** row) > + (2 ** row)) \ > begin \ > for (range = start; range < (start + (2 ** row)); range = range + 1) \ > begin \ > r[row] = (r[row] | i[range]); \ > end \ > end \ > end \ > assign o[row] = r[row]; \ > end \ > end \ > endgenerate \ > endmodule > > `ENCODER(enc1, 1) > `ENCODER(enc2, 2) > `ENCODER(enc3, 3) > `ENCODER(enc4, 4) > `ENCODER(enc5, 5) I just had a very interesting and educational chat on the Verilog news list about this macro ! Learned loads of good things about Verilog, and my _unconventional_ use of Verilog macros caused some intrest. It's apparent to me now that what I did, due to not understanding some finner points of Verilog, was fall back on the macro system to create a Forth style generating word ! And then used that word to make the Verilog source that I wanted. Apparently this isn't a much used or loved feature of Verilog, but it ties in with my thoughts on macro systems and how much Forth is just a macro system. ! A very good macro system I might add. Chris
[toc] | [prev] | [next] | [standalone]
| From | Jan Coombs <jan_2011-02@murray-microft.co.uk> |
|---|---|
| Date | 2011-04-10 23:20 +0100 |
| Message-ID | <RqidnTp1uLPUsD_QnZ2dnUVZ8gednZ2d@brightview.co.uk> |
| In reply to | #1052 |
On 07/04/11 23:26, Chris Hinsley wrote:
> On 2011-04-03 13:20:34 +0100, Chris Hinsley said:
>
>> Hurrah, finally, I managed it. Gee that was tough but educational. !
Good, glad you could hack it. I tried to write a similar low level
solution in MyHDL, but could not get it to convert to VHDL or Verilog.
The following was someone else's work in MyHDL. The code is high
level, but presumably the Verilog synthesizer can produce correct
results. Using MyHDL allows quick interactive development of both
the test harness and the hardware description.
Jan Coombs
--
#!/usr/bin/env python
from myhdl import *
def hotBit2index(iv, ov, Width=4):
@always_comb
def logic():
ov.next = 0 # avoid state
for i in range(len(iv)):
if iv[i] == 1:
ov.next = i
return logic
Width=4
iv = Signal(intbv(0)[Width**2:])
ov = Signal(intbv(0)[Width:])
toVerilog(hotBit2index, iv, ov, Width)
toVHDL(hotBit2index, iv, ov, Width)
# set up a test bench
#from random import randrange
def tb():
dut = hotBit2index(iv, ov, Width)
@instance
def check():
yield delay(10)
for i in range(16):
iv.next = 2**i
yield delay(10)
print i, iv, ov
#assert 2**ov == iv
return dut, check
# the entry point for the py.test unit test framework
def test_ehb():
sim = Simulation(tb())
sim.run()
test_ehb()
[toc] | [prev] | [next] | [standalone]
| From | rickman <gnuarm@gmail.com> |
|---|---|
| Date | 2011-04-11 10:36 -0700 |
| Message-ID | <7a01f4fb-b091-4d3b-9887-9e3a4135c8e5@v16g2000vbq.googlegroups.com> |
| In reply to | #987 |
On Apr 3, 8:20 am, Chris Hinsley <chris.hins...@gmail.com> wrote: > Hurrah, finally, I managed it. Gee that was tough but educational. ! > > Thanks Jan for putting me on the path. :) > > `define ENCODER(NAME, BITS) \ > module NAME(i, o); \ > parameter WIDTH = (2 ** BITS); \ > input [(WIDTH - 1):0] i; \ > output [(BITS - 1):0] o; \ > reg [(BITS - 1):0] r; \ > genvar row; \ > generate \ > begin \ > for (row = 0; row < BITS; row = row + 1) \ > begin : G \ > always \ > begin \ > integer start; \ > integer range; \ > r[row] = 0; \ > for (start = (2 ** row); start < WIDTH; start = start + (2 ** row) > + (2 ** row)) \ > begin \ > for (range = start; range < (start + (2 ** row)); range = range + 1) \ > begin \ > r[row] = (r[row] | i[range]); \ > end \ > end \ > end \ > assign o[row] = r[row]; \ > end \ > end \ > endgenerate \ > endmodule > > `ENCODER(enc1, 1) > `ENCODER(enc2, 2) > `ENCODER(enc3, 3) > `ENCODER(enc4, 4) > `ENCODER(enc5, 5) I didn't go through your code to see exactly how it works, but here is what I came up with in VHDL using functions. function encoder(in_vec : unsigned) return unsigned is constant encode_width : integer := log2int(in_vec'length); variable temp : unsigned (encode_width - 1 downto 0) := (others => '0'); variable ref : unsigned (in_vec'high downto 0) := (0 =>'1', others => '0'); begin for i in in_vec'reverse_range loop report "Processing bit " & integer'image(i); if (in_vec = ref) then temp := to_unsigned(i, encode_width); end if; ref := ref sll 1; end loop; return (temp); end function; I didn't check to see how efficiently it synthesizes. But it is fairly compact and clear. Rick
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-04-11 20:16 +0100 |
| Message-ID | <2011041120165770637-chrishinsley@gmailcom> |
| In reply to | #959 |
Here's what I ended up with after my chat on the Verilog news group. Many thanks to Johnathon Bromley for his crash tutoring on Verilog. :) module enc(i, o); parameter OUT_BITS = 2; localparam IN_BITS = 1 << OUT_BITS; input [IN_BITS-1:0] i; output [OUT_BITS-1:0] o; reg [OUT_BITS-1:0] o; always @(*) begin integer n; o = 0; for (n = 0; n < IN_BITS; n += 1) if (i[n]) o |= n; end endmodule This turns into very nice hardware in Quartus. Chris
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.forth
csiph-web