Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `timescale 1ns/100ps
- module ads1018 (
- input reset,
- input clk_i,
- output sclk_adc,
- output reg cs,
- input din, //принимаем результат
- output dout, //отправляем вопрос к каналам
- output reg [11:0]o_ch1,
- output reg [11:0]o_ch2,
- output reg [11:0]o_ch3,
- output reg [11:0]o_ch4,
- input ena_i
- );
- reg [8:0] counter; // reg to enter 32- or 16-bit transmission cycle
- // operating way
- // cs high 5*40.69 ns
- parameter csHigh = 5;
- //sclk low 3*40.69 ns
- parameter sclkLow = 3;
- //sclk high 4*40.69 ns
- parameter sclkPer = 8*16-4; // 16 периодов по восемь тактов/ не учитывается последний низкий sclk
- //sclk low 4*40.69 ns
- //sclk low 3*40.69 ns
- //repeat
- wire drdy_check ;
- reg start_conv = 0;
- reg start;
- reg main_reg;
- wire pos_sclk, neg_sclk;
- assign pos_sclk = sclk_adc & ~main_reg;
- assign neg_sclk = ~sclk_adc & main_reg;
- assign drdy_check = ~cs & ~din & ~start_conv;// start conversation when curcuit is ready to transmit and cs is low
- reg [2:0] dur_sclk = -1;
- assign sclk_adc = start_conv & dur_sclk[2];
- wire [15:0] i_ch1 = 16'h8888;
- wire [15:0] i_ch2 = 16'hAAAA;
- wire [15:0] i_ch3 = 16'h1111;
- wire [15:0] i_ch4 = 16'hF0F0;
- // get data
- wire [15:0] reg_in;
- reg [15:0] reg_in_next;
- reg [3:0]cnt_adc_p = 0;
- // give data
- reg [15:0] reg_out;
- wire [15:0] reg_out_next;
- assign dout = start_conv & reg_out[15];
- assign reg_out_next = {reg_out[14:0], 1'b0};
- ////////////
- reg [3:0]cnt_adc_n = 0;
- reg [1:0]ch_cnt;
- assign reg_in = reg_in_next;
- initial begin
- cs<=1; o_ch1 <=0;o_ch2 <=0;o_ch3 <=0;o_ch4 <=0;
- end
- always @(posedge clk_i or posedge reset)
- begin
- if (reset)
- begin
- counter <= 1'b0;
- ch_cnt <= 1'b0;
- start <=0;
- cnt_adc_p <= 0;
- cnt_adc_n <= 0;
- reg_out = i_ch1;
- end
- else
- begin
- main_reg <= sclk_adc;
- if (ena_i) begin start<=1'b1; end
- if (start) counter <= counter + 1;
- if (counter == csHigh-1'd1) begin start <=0; cs<=0; counter <=0; end
- if (drdy_check) start_conv <= 1;
- if (start_conv)
- begin
- //if(neg_sclk & sclk_adc) reg_in_next <= { reg_in_next[14:0],din};
- //if(pos_sclk & ~sclk_adc)
- counter <= counter + 1;
- dur_sclk <= dur_sclk - 1;
- if (counter == sclkPer+sclkLow-1'b1)
- begin
- counter <= 0;
- dur_sclk <= -1;
- cs <= 1;
- ch_cnt <= ch_cnt + 1;
- start_conv <= 0;
- if (ch_cnt == 2'd0) begin reg_out = i_ch2; o_ch1 = reg_in; end
- if (ch_cnt == 2'd1) begin reg_out = i_ch3; o_ch2 = reg_in; end
- if (ch_cnt == 2'd2) begin reg_out = i_ch4; o_ch3 = reg_in; end
- if (ch_cnt == 2'd3) begin reg_out = i_ch1; o_ch4 = reg_in; end
- end
- end
- end
- end
- always @(negedge sclk_adc) reg_in_next <= { reg_in_next[14:0],din};
- always @(posedge sclk_adc)
- begin
- cnt_adc_p <= cnt_adc_p + 1;
- if (cnt_adc_p != 0) reg_out <= reg_out_next;
- end
- endmodule
- `timescale 1ns/1ps
- module tb;
- reg din = 0;
- reg [3:0] sclk_adc1 = 0;
- reg [8:0]counter =0;
- reg clk,reset,ena_i;
- initial begin
- reset = 1;
- #5;
- reset = 0;
- clk = 0;
- ena_i = 0;
- #10;
- ena_i = 1;
- #5;
- ena_i = 0;
- #500;
- ena_i = 1;
- #5;
- ena_i = 0;
- #500;
- ena_i = 1;
- #5;
- ena_i = 0;
- #500;
- ena_i = 1;
- #5;
- ena_i = 0;
- #500;
- ena_i = 1;
- #5;
- ena_i = 0;
- #500;
- ena_i = 1;
- #5;
- ena_i = 0;
- #500;
- ena_i = 1;
- #5;
- ena_i = 0;
- #500;
- end
- initial begin
- din = 0;
- #50;
- din = 1;
- #300;
- din = 0;
- #600;
- din = 1;
- #300;
- din = 0;
- #800;
- din = 1;
- #300;
- din = 0;
- #800;
- din = 1;
- #300;
- din = 0;
- #800;
- din = 1;
- #300;
- end
- always #1 clk = ~clk;
- always @ (posedge clk)
- begin
- counter <= counter +1;
- if (counter > 4'hb) sclk_adc1 = sclk_adc1 +1;
- else sclk_adc1 = 0;
- end
- ads1018 DUT
- (
- .reset(reset),
- .clk_i(clk),
- .sclk_adc (sclk_adc),
- .cs(cs),
- .din(din), //принимаем результат
- .dout(), //отправляем вопрос к каналам
- .o_ch1(),
- .o_ch2(),
- .o_ch3(),
- .o_ch4(),
- .ena_i(ena_i)
- );
- //initial #2000 $stop;
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement