Foreword:
This column aims to record high-frequency pen interview hand-torn code questions for digital front-end autumn recruits. All articles in this column provide principle analysis, codes and waveforms, and all codes have been verified by myself.
The directory is as follows:
1. Digital IC hand-tear code-frequency divider (any even number frequency division)
2. Digital IC hand-tear code-frequency divider (any odd frequency division)
3. Digital IC hand-tear code-frequency divider (any decimal frequency division)
4. Digital IC hand tearing code - asynchronous reset and synchronous release
5. Digital IC hand tear code - edge detection (rising edge, falling edge, double edge)
6. Digital IC hand tearing code-sequence detection (state machine writing method)
7. Digital IC hand tearing code-sequence detection (shift register writing method)
8. Digital IC tearing code - half adder, full adder
9. Digital IC hand tearing code - serial to parallel, parallel to serial
10. Digital IC hand tearing code-data bit width converter (width-narrow, narrow-width conversion)
11. Digital IC hand tearing code - finite state machine FSM - beverage machine
12. Digital IC hand tear code - handshake signal (READY-VALID)
14. Digital IC hand tearing code - Telink micro written test questions
15. Digital IC hand tearing code - Pingtouge technology final face hand tearing real question
16. Digital IC manual tearing code-Zhaoyi innovation written test real questions
18. Digital IC tearing code - dual-port RAM (dual-port-RAM)
...Continually updated
For more hand-tearing code questions, you can go to the digital IC hand-tearing code--question bank
Table of contents
topic description
Input continuous data streams to get the sum value of every 256 data streams. The timing diagram is as follows:
The input is i0, i1, i2,…, i253, i254,….accounting for 1 clock cycle, the output sum0 is the sum value of i0 +i2+….+i254 (addition at intervals), and sum1 is i1+i3+…. +i255, sum2 is i2+i4+….+i256, and so on, each output occupies one clock cycle, and the relative delay relationship between Sum0 and i0 is arbitrary. Assuming that the input i0, i1, i254, ... are 8-bit values, and the output sum please choose a suitable bit width that will not lose precision, and use the verilog language to achieve the above requirements in the most resource-saving way you think.
problem solving ideas
The summation of this question is actually relatively simple, but the key is to use the most resource-efficient way to achieve the requirements. All inputs are 8bit, sum0 plus sum1 is from i0 to i255, and 256 8bit numbers are added. Therefore, the addition of 256 8-bit numbers needs to be represented by 16-bit numbers, so set the sum to 15 bits. And there are rules:
sum2=sum0-i0+i256,sum3=sum1-i1+i257
You can use a space datain_store with a depth of 257*8bit bits to store i0-i256, and then every time a value is entered, datain_store will shift 8bit to store the new incoming number. Then use two sums, one sum outputs the sum of odd 128 items, and one sum outputs the sum of even 128 items.
the code
module pip_sum(
input clk ,
input rstn ,
input [7:0] datain ,
input datain_ena ,
output [14:0] sum ,
output dataout_ena
);
reg [8*257-1:0] datain_store; //DEPTH = 2056
reg [7:0] count;
reg [14:0] sum_odd,sum_even;
reg datain_ena_onebeat;
reg flag;
always @(posedge clk)begin
if(datain_ena)begin
datain_store <= {datain_store[8*256-1:0],datain}; //left shift 8bit, store datain in low 8bit
end
end
always @(posedge clk)begin
if(!rstn)begin
count <= 8'd0;
end
else if(datain_ena_onebeat == 1'b1 && count < 8'd255)begin
count <= count + 1'b1;
end
else if(datain_ena_onebeat == 1'b1 && count == 8'd255)begin
count <= 8'd0;
end
end
always @(posedge clk)begin
if(!rstn)
flag <= 1'b0;
else if(count == 8'd255)
flag <= 1'b1; //
end
wire [7:0] look;
assign look = datain_store[7:0];
always @(posedge clk)begin
if(!rstn)begin
sum_odd <= 15'd0;
sum_even <= 15'd0;
end
else begin
datain_ena_onebeat <= datain_ena;
if(datain_ena_onebeat)
case(count[0])
0:begin
if(flag==0)
sum_even <= sum_even + datain_store[7:0];
else
sum_even <= sum_even - datain_store[8*257-1:8*256] + datain_store[7:0];
end
1:begin
if(flag==0)
sum_odd <= sum_odd + datain_store[7:0];
else
sum_odd <= sum_odd - datain_store[8*257-1:8*256] + datain_store[7:0];
end
endcase
end
end
reg [14:0] sum_odd_onebeat,sum_even_onebeat;
always @(posedge clk)begin
sum_odd_onebeat <= sum_odd;
sum_even_onebeat <= sum_even;
end
assign sum = (count[0]) ? sum_odd_onebeat: sum_even_onebeat;
assign dataout_ena = flag;
endmodule
testbench
module pip_sum_tb();
reg clk,rstn;
reg [15:0] count;
reg [7:0] datain;
reg datain_ena;
wire [14:0] sum;
wire dataout_ena;
always #5 clk <= ~clk;
initial begin
clk <= 1'b0;
rstn <= 1'b0;
#16
rstn <= 1'b1;
#20
datain_ena <= 1'b1;
#10000
$finish();
end
initial begin
datain <= 8'd0;
count <= 1'b0;
forever begin
@(posedge clk)begin
if(datain_ena == 1)begin
if(count < 255)begin
datain <= 1'b0;
end
else
datain <= datain + 1'b1;
count <= count + 1'b1;
end
end
end
end
//dump fsdb
initial begin
$fsdbDumpfile("pip_sum.fsdb");
$fsdbDumpvars(0);
end
pip_sum u_pip_sum(
.clk (clk) ,
.rstn (rstn) ,
.datain (datain) ,
.datain_ena (datain_ena),
.sum (sum) ,
.dataout_ena (dataout_ena)
);
endmodule
output waveform
For the convenience of checking the correctness of the results, let the first 256 cycles of datain be 0, so that the output sum0 and sum1 are both 0, and then let datain increment as a positive integer sequence. As can be seen from the output results, it is consistent with our expectations, sum0=sum1=0, sum2=sum0-i0+i256=0-0+1=1; sum3=sum1-i1+i257=0-0+2=2, and so on.
For more hand-tearing code questions, you can go to the digital IC hand-tearing code--question bank