状态机练习-基于DAC8168C DAC电压输出

DAC8168C 时序图:

 数据格式:

一组数据是32bit 至少产生32个sclk.

发送数据是在SCLK的上升延发出

利用状态机实现每个通道输出的电压不一样,每个状态之间延时50ms进行切换

状态机如下图:

代码:

  1 module    dac8168(
  2                 clk,
  3                 rst_n,
  4                 
  5                 ldac_n,
  6                 clr_n,
  7                 sclk,
  8                 sync_n,
  9                 din
 10                 );
 11 
 12 parameter     CONTROL         = 4'b0010;
 13 parameter     ADDRESS         = 4'b0000;
 14 parameter     DAC_DATA         = 14'd300; //0.093V
 15 //parameter     DAC_DATA         = 14'd16383; //4.98V
 16 parameter     FEATURE         = 4'b0101;
 17 
 18 parameter    DLY_50MS        = 2_500_000;
 19 
 20 parameter    A0 = 0;
 21 parameter    A1 = 1;
 22 parameter    A2 = 2;
 23 parameter    A3 = 3;
 24 parameter    A4 = 4;
 25 parameter    A5 = 5;
 26 parameter    A6 = 6;
 27 parameter    A7 = 7;
 28 
 29 
 30 input     clk;
 31 input     rst_n;
 32 
 33 output     ldac_n;
 34 output    clr_n;
 35 output     sclk;
 36 output     sync_n;
 37 output    din;
 38 
 39 
 40 assign    ldac_n = 1;
 41 assign     clr_n = 1;
 42 
 43 reg     sclk;
 44 reg     sync_n;
 45 reg        din;
 46 reg        flag_add;
 47 
 48 wire    add_cnt0;
 49 wire    end_cnt0;
 50 
 51 wire    add_cnt1;
 52 wire    end_cnt1;
 53 
 54 wire    add_cnt2;
 55 wire    end_cnt2;
 56 
 57 wire    A02A1_start;
 58 wire    A12A2_start;
 59 wire    A22A3_start;
 60 wire    A32A4_start;
 61 wire    A42A5_start;
 62 wire    A52A6_start;
 63 wire    A62A7_start;
 64 wire    A72A0_start;
 65 
 66 wire [32-1:0]     data;
 67 reg  [14-1:0]    dout;
 68 reg     [4-1: 0]    dac_address;
 69     
 70 reg  [3-1 :0]     cnt0;//用来计数SCLK
 71 reg  [6-1 :0]     cnt1; //用来计数字节个数
 72 reg  [22-1:0]     cnt2;  //用来延时,An到An+1的间隔时间
 73 reg     [3-1 :0]    state_c;
 74 reg     [3-1 :0]    state_n;
 75 
 76 always @(posedge clk or negedge rst_n)begin
 77     if(!rst_n)begin
 78         cnt0 <= 0;
 79     end
 80     else if(add_cnt0)begin
 81         if(end_cnt0)begin
 82             cnt0 <= 0;
 83         end
 84         else begin
 85             cnt0 <= cnt0 + 1;
 86         end
 87     end
 88 end
 89 
 90 assign add_cnt0 = flag_add;
 91 assign end_cnt0 = add_cnt0 && cnt0 == 4 - 1;
 92 
 93 
 94 always @(posedge clk or negedge rst_n)begin
 95     if(!rst_n)begin
 96         cnt1 <= 0;
 97     end
 98     else if(add_cnt1)begin
 99         if(end_cnt1)begin
100             cnt1 <= 0;
101         end
102         else begin
103             cnt1 <= cnt1 + 1;
104         end
105     end
106 end
107 
108 assign add_cnt1 = end_cnt0;
109 assign end_cnt1 = add_cnt1 && cnt1 == 33-1;
110 
111 
112 //增加一个信号,用来区分哪段是延时50ms技术,哪段时间是发产生sclk并发送数据
113 always @(posedge clk or negedge rst_n)begin
114     if(!rst_n)begin
115         flag_add <= 1;
116     end
117     else if(end_cnt1)begin
118         flag_add <= 0;
119     end
120     else if(end_cnt2)begin //An到An+延迟时间结束之后,再次启动
121         flag_add <= 1;
122     end
123 end
124 
125 always @(posedge clk or negedge rst_n)begin
126     if(!rst_n)begin
127         cnt2 <= 0;
128     end
129     else if(add_cnt2)begin
130         if(end_cnt2)begin
131             cnt2 <= 0;
132         end
133         else begin
134             cnt2 <= cnt2 + 1;
135         end
136     end
137 end
138 
139 assign add_cnt2 = flag_add == 0;
140 assign end_cnt2 = add_cnt2 && cnt2 == DLY_50MS - 1;
141 
142 always @(posedge clk or negedge rst_n)begin
143     if(!rst_n)begin
144         sclk <= 1;
145     end
146     else if(add_cnt0 && cnt0 == 2 - 1)begin
147         sclk <= 0;
148     end
149     else if(end_cnt0)begin
150         sclk <= 1;
151     end
152 end
153 
154 always @(posedge clk or negedge rst_n)begin
155     if(!rst_n)begin
156         sync_n <= 1;
157     end
158     else if(add_cnt0 && cnt0 == 3-1 && cnt1 == 0)begin
159         sync_n <= 0;
160     end
161     else if(end_cnt0 && cnt1 == 33-1)begin
162         sync_n <= 1;
163     end
164 end
165 
166 //第一段,状态跳转
167 always @(posedge clk or negedge rst_n)begin
168     if(!rst_n)begin
169         state_c <= A0;
170     end
171     else begin
172         state_c <= state_n;
173     end
174 end
175 
176 //第二段,组合逻辑,罗列出所有跳转条件
177 always @(*)begin
178     case(state_c)
179         
180         A0:begin
181             if(A02A1_start)begin
182                 state_n = A1;
183             end
184             else begin
185                 state_n = state_c;
186             end
187         end
188 
189         A1:begin
190             if(A12A2_start)begin
191                 state_n = A2;
192             end
193             else begin
194                 state_n = state_c;
195             end
196         end
197         
198         A2:begin
199             if(A22A3_start)begin
200                 state_n = A3;
201             end
202             else begin
203                 state_n = state_c;
204             end
205         end
206         
207         A3:begin
208             if(A32A4_start)begin
209                 state_n = A4;
210             end
211             else begin
212                 state_n = state_c;
213             end
214         end
215         
216         A4:begin
217             if(A42A5_start)begin
218                 state_n = A5;
219             end
220             else begin
221                 state_n = state_c;
222             end
223         end
224         
225         A5:begin
226             if(A52A6_start)begin
227                 state_n = A6;
228             end
229             else begin
230                 state_n = state_c;
231             end
232         end
233         
234         A6:begin
235             if(A62A7_start)begin
236                 state_n = A7;
237             end
238             else begin
239                 state_n = state_c;
240             end
241         end
242         
243         A7:begin
244             if(A72A0_start)begin
245                 state_n = A0;
246             end
247             else begin
248                 state_n = state_c;
249             end
250         end
251     
252         default: begin
253             state_n = A0;
254         end
255     endcase 
256 end
257 
258 
259 //第三段,设计条件转移
260 assign A02A1_start = state_c == A0 && end_cnt2;
261 assign A12A2_start = state_c == A1 && end_cnt2;
262 assign A22A3_start = state_c == A2 && end_cnt2;
263 assign A32A4_start = state_c == A3 && end_cnt2;
264 assign A42A5_start = state_c == A4 && end_cnt2;
265 assign A52A6_start = state_c == A5 && end_cnt2;
266 assign A62A7_start = state_c == A6 && end_cnt2;
267 assign A72A0_start = state_c == A7 && end_cnt2;
268 
269 //第四段, 产生输出
270 always @(posedge clk or negedge rst_n)begin
271     if(!rst_n)begin
272         din <= 1;
273     end
274     else if(end_cnt0 && cnt1 >= 0 && cnt1 < 32)begin //在SCLK的上升沿发送数据
275         din <= data[31-cnt1];
276     end
277 end
278 
279 assign data = {1'b0, 3'b000, CONTROL, dac_address, dout, 2'b00, FEATURE};
280 
281 //通道地址 , 及每个通道的数据赋值
282 always @(*)begin
283     if(state_c == A0)begin
284         dac_address = A0;
285         dout = 1000;  //0.307V
286     end
287     else if(state_c == A1)begin
288         dac_address = A1;
289         dout = 2000;    //0.611V
290     end
291     else if(state_c == A2)begin
292         dac_address = A2;
293         dout = 3000;    //0.916V
294     end
295     else if(state_c == A3)begin
296         dac_address = A3;
297         dout = 4000;    //1.221V
298     end
299     else if(state_c == A4)begin
300         dac_address = A4;
301         dout = 5000;    //1.526V
302     end
303     else if(state_c == A5)begin
304         dac_address = A5;
305         dout = 6000;    //1.831V
306     end
307     else if(state_c == A6)begin
308         dac_address = A6;
309         dout = 7000;    //2.136V
310     end
311     else begin
312         dac_address = A7;
313         dout = 8000;    //2.441V
314     end
315 end
316 
317 endmodule

测试代码:

`timescale 1us/100ns

module dac8168_sim();
reg             clk        ;
reg             rst_n    ;
wire             ldac_n    ;
wire             clr_n    ;
wire             sclk       ;
wire             sync_n    ;
wire             din       ;

parameter CLK_CYCLE = 20;

initial begin
    clk = 0;
    #CLK_CYCLE;
    forever #(CLK_CYCLE/2) clk = ~clk;
end

initial begin
    rst_n = 0;
    #(CLK_CYCLE*200);
    rst_n = 1;
end

dac8168 u1(
            .clk            (    clk        ),
            .rst_n            (    rst_n    ),
            
            .ldac_n            (    ldac_n    ),
            .clr_n            (    clr_n    ),
            .sclk            (    sclk    ),
            .sync_n            (    sync_n    ),
            .din            (    din        )
        );                        
            
endmodule


    

 

仿真波形:

 

 下图中的数据格式:

assign data = {1'b0, 3'b000, CONTROL, dac_address, dout, 2'b00, FEATURE};

parameter CONTROL = 4'b0010;

dac_address = 4‘b0001;

dout = 2000

parameter FEATURE = 4'b0101;

 

posted @ 2022-04-05 21:40  MyBooks  阅读(161)  评论(0编辑  收藏  举报