赞
踩
module top_module ( input clk, input shift_ena, input count_ena, input data, output [3:0] q); reg [3:0] cnt; always@(posedge clk) begin if(shift_ena) cnt <= {cnt[2:0],data}; else if(count_ena) cnt <= cnt-1'b1; else cnt <= cnt; end assign q = cnt; endmodule
隐含条件应该是不重叠。
module top_module ( input clk, input reset, // Synchronous reset input data, output start_shifting); parameter s0 = 3'd0, s1 = 3'd1, s2 = 3'd2; parameter s3 = 3'd3, s4 = 3'd4; reg [2:0] cs,ns; always@(posedge clk) begin if(reset) cs <= s0; else cs <= ns; end always@(*) begin case(cs) s0: ns = data ? s1 : s0; s1: ns = data ? s2 : s0; s2: ns = data ? s2 : s3; s3: ns = data ? s4 : s0; s4: ns = s4; default: ns = s0; endcase end assign start_shifting = cs==s4; endmodule
FSM enable shift register
module top_module ( input clk, input reset, // Synchronous reset output shift_ena); parameter s0 = 3'd0, s1 = 3'd1, s2 = 3'd2; parameter s3 = 3'd3, s4 = 3'd4; reg [2:0] cs,ns; always@(posedge clk) begin if(reset) cs <= s0; else cs <= ns; end always@(*) begin case(cs) s0: ns = s1; s1: ns = s2; s2: ns = s3; s3: ns = s4; s4: ns = s4; default: ns = s0; endcase end assign shift_ena = cs==s4 ? 1'b0 : 1'b1;
复位信号有效,进入状态s0,复位撤销,进入s1,持续到s3, 4个时钟周期为1,之后为0.
下一种方法:计数器
module top_module ( input clk, input reset, // Synchronous reset output shift_ena); reg [1:0] cnt; wire a,b; assign a = shift_ena; //开始计数 assign b = a && cnt==2'd3; //计满四个周期,停止计数。 always@(posedge clk) begin if(reset) cnt <= 2'd0; else cnt <= a ? (b ? 2'd0 : cnt+1'b1) : 2'd0; end always@(posedge clk) begin if(reset) shift_ena <= 1'b1; else if(b) shift_ena <= 1'b0; end endmodule
module top_module ( input clk, input reset, // Synchronous reset input data, output shift_ena, output counting, input done_counting, output done, input ack ); parameter s0 = 4'd0, s1 = 4'd1, s2 = 4'd2; parameter s3 = 4'd3, s4 = 4'd4; //1101 parameter s5 = 4'd5, s6 = 4'd6, s7 = 4'd7; //移位4个时钟 parameter cnt = 4'd8, WAIT = 4'd9; //计数和等待 reg [3:0] cs,ns; always@(posedge clk) begin if(reset) cs <= s0; else cs <= ns; end always@(*) begin case(cs) s0: ns = data ? s1 : s0; s1: ns = data ? s2 : s0; s2: ns = data ? s2 : s3; s3: ns = data ? s4 : s0; s4: ns = s5; s5: ns = s6; s6: ns = s7; s7: ns = cnt; cnt: ns = done_counting ? WAIT : cnt; WAIT: ns = ack ? s0 : WAIT; default: ns = s0; endcase end assign shift_ena = cs==s4 || cs==s5 || cs==s6 || cs==s7; assign counting = cs==cnt; assign done = cs==WAIT; endmodule
module top_module ( input clk, input reset, // Synchronous reset input data, output [3:0] count, output counting, output done, input ack ); parameter s0 = 4'd0, s1 = 4'd1, s2 = 4'd2; parameter s3 = 4'd3, s4 = 4'd4; //1101 parameter s5 = 4'd5, s6 = 4'd6, s7 = 4'd7; //移位4个时钟 parameter cnt = 4'd8, WAIT = 4'd9; //计数和等待 reg [3:0] cs,ns; reg [3:0] in; reg [15:0] counter; always@(posedge clk) begin if(reset) counter <= 16'd0; else if(ns==WAIT) counter <= 16'd0; else if(ns==cnt) counter <= counter + 1'b1; end reg [3:0] delay; always@(*) begin if(counter<=1000) delay = 4'd0; else if(counter>1000 && counter<=2000) delay = 4'd1; else if(counter>2000 && counter<=3000) delay = 4'd2; else if(counter>3000 && counter<=4000) delay = 4'd3; else if(counter>4000 && counter<=5000) delay = 4'd4; else if(counter>5000 && counter<=6000) delay = 4'd5; else if(counter>6000 && counter<=7000) delay = 4'd6; else if(counter>7000 && counter<=8000) delay = 4'd7; else if(counter>8000 && counter<=9000) delay = 4'd8; else if(counter>9000 && counter<=10000) delay = 4'd9; else if(counter>10000 && counter<=11000) delay = 4'd10; else if(counter>11000 && counter<=12000) delay = 4'd11; else if(counter>12000 && counter<=13000) delay = 4'd12; else if(counter>13000 && counter<=14000) delay = 4'd13; else if(counter>14000 && counter<=15000) delay = 4'd14; else delay = 4'd15; end wire exact_sum; assign exact_sum = (counter==(in + 1)*1000) ? 1'b1 : 1'b0; always@(posedge clk) begin if(reset) cs <= s0; else cs <= ns; end always@(*) begin case(cs) s0: ns = data ? s1 : s0; s1: ns = data ? s2 : s0; s2: ns = data ? s2 : s3; s3: ns = data ? s4 : s0; s4: begin ns = s5; in[3] = data; end s5: begin ns = s6; in[2] = data; end s6: begin ns = s7; in[1] = data; end s7: begin ns = cnt;in[0] = data; end cnt: ns = exact_sum ? WAIT : cnt; WAIT: ns = ack ? s0 : WAIT; default: ns = s0; endcase end assign count = cs==cnt ? (in-delay) : 4'd0; assign counting = cs==cnt; assign done = cs==WAIT; endmodule
最后一个独热码,就按照状态转移图写就行了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。