EmbDev.net

Forum: FPGA, VHDL & Verilog Serializer verilog


von Atalin (Guest)


Rate this post
useful
not useful
Hi! I am writing a code for a serializer. The problem is that I have 
only 1s as output but I want to see the input bitstream, obviously. Do 
you have any suggestion? Thanks.

The code is the following:
1
// Serializer
2
3
`timescale 1ns / 1ps
4
5
module serializer (data_in, send, clk, load, rst, data_out);
6
7
input wire [11:0] data_in;
8
input wire send, clk, load, rst;
9
10
output reg data_out;
11
12
reg [11:0] temp_data_out;
13
integer i;
14
integer j;
15
16
always @ (posedge clk) 
17
begin
18
  if (rst) begin
19
    data_out <= 1'b0;
20
    temp_data_out <= 12'b0;
21
  end
22
  else if (load)
23
    for(i=0; i<12; i=i+1)
24
      temp_data_out[i] <= data_in[i];
25
  else if (send)
26
    for(j=0; j<12; j=j+1)
27
      data_out <= temp_data_out[j];
28
    //data_out <= temp_data_out[0];
29
    //temp_data_out <= {temp_data_out[10:0], 1'b0};
30
end
31
32
endmodule //end module serializer

The testbench is
1
`include "serializer.v"
2
`timescale 1ns / 1ps
3
4
module serializer_tb();
5
// Declare inputs as regs and outputs as wires
6
reg [11:0] data_in;
7
reg send, clk, load, rst;
8
wire data_out;
9
10
// Initialize all variables
11
initial begin          
12
  clk = 1;       // initial value of clock
13
  rst = 1;       // initial value of reset
14
  load = 0;
15
  send = 0;
16
  data_in = 12'b110110110110;
17
  #15 rst = 0;   // De-assert the reset
18
  #13 load = 1;
19
  #15 load = 0;
20
  #5 send = 1;
21
  #125 send = 0;
22
  #10 data_in = 12'b100100010001;
23
  #10 load = 1;
24
  #15 load = 0;
25
  #5 send = 1;
26
  #125 send = 0;
27
end
28
29
// Clock generator
30
always begin
31
  #5 clk = ~clk; // Toggle clock every 5 ns - 100 MHz
32
end
33
34
// Connect DUT to test bench
35
serializer U_serializer (data_in, send, clk, load, rst, data_out);
36
37
endmodule

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Have a look what a for loop does in Verilog: it produces parallel 
hardware. It looks like you expect something entirely different.

BTW:
I assume this here:
1
    for(i=0; i<12; i=i+1)
2
      temp_data_out[i] <= data_in[i];
Could be cut down to one line:
1
      temp_data_out <= data_in;
But I may be completely wrong because I'm doing VHDL usually... ;-)

: Edited by Moderator
von Klakx (Guest)


Rate this post
useful
not useful
you toggle "load" at #13 and #15, but your clock toggles with #5 (and 
rising edges with 10). I think you will miss easily signals in that 
style

improve your testbench with:
1
@(posedge clk) 
2
load = 1;
3
@(posedge clk)
4
load = 0;

furthermore:
1
for(j=0; j<12; j=j+1)
2
      data_out <= temp_data_out[j];
3
4
// is the same like
5
      data_out <= temp_data_out[11];
In a N-serializer you have to use a 1-bit clock and your inputs stays at 
the correct time every N cycles or for N cycles.

von Atalin (Guest)


Rate this post
useful
not useful
Thank you! I tried to modify that line but nothig has changed...

von Atalin (Guest)


Rate this post
useful
not useful
Hi! For what concern the tesbench, in the simulation result I can see 
that when load is high, it returns to 0 after 15 ns. So, it is high for 
at least 1 clock cycle.

If I write
1
      data_out <= temp_data_out[11];

how I can see as output the whole bit stream? In this way I can see only 
temp_data_out[11] and not all the bits in that array

von VHDL hotline (Guest)


Rate this post
useful
not useful
Why you commented this line?
1
    //temp_data_out <= {temp_data_out[10:0], 1'b0};

This is basically what the serializer should do, shifting out the bits. 
Also, in hardware the for loops are unrolled and so all happens in one 
clock cycle and the last assignment wins. In your case, the second for 
loop always results to 'data_out <= temp_data_out[11]'. Discard the for 
loops and try like this:
1
always @ (posedge clk) 
2
begin
3
  if (rst) begin
4
    data_out <= 1'b0;
5
    temp_data_out <= 12'b0;
6
  end
7
  else if (load)
8
      temp_data_out <= data_in;  //take over the vector
9
  else if (send)
10
      data_out <= temp_data_out[11];  //assert the MSBit of the vector at output
11
      temp_data_out <= {temp_data_out[10:0], 1'b0}; //shift the vector by one bit per cycle
12
end

von Atalin (Guest)


Rate this post
useful
not useful
Yes you are absolutely righ, I commented that line because I was not 
sure (I am new in programming so maybe it is easier for me think with 
for loop..!) but I was thinking again about it and you confirmed my 
thought. Thank you very much!

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Atalin wrote:
> I am new in programming
Don't think you are "programming" like a software programmer writes a 
program for a computing device. What you are doing is "describing" 
hardware using a HDL (Hardware Description Language). So at first you 
must have a "picture" of that hardware on a sheet of paper or at least 
in your brain. Then you can describe it with Verilog (or VHDL or 
whatsoever).

By doing this don't let you betray by "false friends" like that 
"for-loop" in the posts above.

VHDL hotline wrote:
> This is basically what the serializer should do, shifting out the bits
But of course this serializer also could be done with a 12:1 
multiplexer. So with each clock a counter must count up and then this 
counter can be used for indexing the desired bit.

von Atalin (Guest)


Rate this post
useful
not useful
Hi guys! I am here again for asking some help. Here I have the testbench 
of the serializer (I slightly modify it in order to have random bits as 
input). I would like to add a kind of receiver (like a serial-in 
parallel-out register) in order to check automatically if the input 
parallel data are equal to the output. How can I do this? Thanks
1
`include "serializer.v"
2
`timescale 1ns / 1ps
3
4
module serializer_tb();
5
// Declare inputs as regs and outputs as wires
6
reg [11:0] data_in;
7
reg send, clk, load, rst;
8
wire data_out;
9
10
11
// Initialize all variables
12
initial begin          
13
  clk = 1;       // initial value of clock
14
  rst = 1;       // initial value of reset
15
  load = 0;
16
  send = 0;
17
  #15 rst = 0;   // De-assert the reset
18
19
  forever begin
20
    foreach(data_in[ii]) data_in[ii] = $urandom;
21
    #13 load = 1;
22
    #15 load = 0;
23
    #5 send = 1;
24
    #85 send = 0;
25
  end
26
end
27
28
// Clock generator
29
always begin
30
  #5 clk = ~clk; // Toggle clock every 5 ns - 100 MHz
31
end
32
33
// Connect DUT to test bench
34
serializer U_serializer (data_in, send, clk, load, rst, data_out);
35
36
endmodule

von Atalin (Guest)


Rate this post
useful
not useful
I find out this solution, maybe someone needs it too :)
1
 initial begin          
2
  clk = 1;       // initial value of clock
3
  rst = 1;       // initial value of reset
4
  load = 0;
5
  send = 0;
6
  #15 rst = 0;   // De-assert the reset
7
8
  forever begin
9
    foreach(data_in[j]) data_in[j] = $urandom;
10
    #13 load = 1;
11
    #15 load = 0;
12
    #5 send = 1;
13
    #20          //header
14
    for(i=0; i<12; i=i+1) begin
15
      #5 reg_sipo[11-i] <= data_out;
16
      end
17
    #5 send = 0;
18
    if(reg_sipo == data_in) check = 0;
19
    else check = 1;
20
  end
21
end

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.