Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #959 > unrolled thread

Verilog macro issue

Started byChris Hinsley <chris.hinsley@gmail.com>
First post2011-04-02 19:36 +0100
Last post2011-04-11 20:16 +0100
Articles 15 — 3 participants

Back to article view | Back to comp.lang.forth


Contents

  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

#959 — Verilog macro issue

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-04-02 19:36 +0100
SubjectVerilog 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]


#960

FromJan Coombs <jan_2011-02@murray-microft.co.uk>
Date2011-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]


#961

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#963

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#964

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#965

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#968

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#971

FromJan Coombs <jan_2011-02@murray-microft.co.uk>
Date2011-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]


#977

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#986

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#987

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#1052

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#1136

FromJan Coombs <jan_2011-02@murray-microft.co.uk>
Date2011-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]


#1157

Fromrickman <gnuarm@gmail.com>
Date2011-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]


#1159

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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