排序电路设计

参考《数字逻辑基础与Verilog设计》的第七章内容

四个8位寄存器,载入四个数据,并进行排序,最终将四个数据从小到大排列。

用两个循环,内循环作比较。外循环计数器cnti,0~2,内循环cntj,1~3。

首先,cnti=0,cntj=1,将R1中、R2数据分别寄存到A\B中,若A大于B,则将A放入R2,B放入A,再将A放入R1。然后计数cntj+1,R3放入B,A\B作比较...直到比较完R4后,跳出内循环,外循环中cnti+1,cntj=cnti+2将此时R2、R3放到A、B进行比较...直到R3、R4完成比较后,结束运算

代码如下。

`timescale 1ns/1ps

module sort(clk,rst_n,s,a,b,c,d,d1,d2,d3,d4,done);

input clk,rst_n,s;
input [7:0] a,b,c,d;
output [7:0] d1,d2,d3,d4;
output done;
reg [7:0] R1,R2,R3,R4,A,B;

parameter S1=8'd0,S2=8'd1,S3=8'd2,S4=8'd3,S5=8'd4,S6=8'd5,S7=8'd6,S8=8'd7;
reg [7:0] state,next_state;
wire co_ab,z1,z0,wrdata,R1_in,R2_in,R3_in,R4_in,A_in,B_in;
reg [1:0] cnti,cntj;
wire en_cnti,en_cntj;

always@(posedge clk or negedge rst_n) begin 
if(~rst_n) state <= S1;
else state <= next_state;

end

always@(*) begin
case(state)
	S1:next_state=s?S2:S1;
	S2:next_state=S3;
	S3:next_state=S4;
	S4:next_state=co_ab?S5:S7;
	S5:next_state=S6;
	S6:next_state=S7;
	S7:next_state=z1?(z0?S8:S2):S3;
	S8:next_state=s?S8:S1;
	default:next_state = S1;
	endcase
end

always@(posedge clk or negedge rst_n) begin
if(~rst_n) 
	R1 <= 8'd0;
else if (R1_in) 
	R1 <= wrdata?a:A;
end


always@(posedge clk or negedge rst_n) begin
if(~rst_n) 
	R2 <= 8'd0;
else if (R2_in) 
	R2 <= wrdata?b:A;
end


always@(posedge clk or negedge rst_n) begin
if(~rst_n) 
	R3 <= 8'd0;
else if (R3_in) 
	R3 <= wrdata?c:A;
end


always@(posedge clk or negedge rst_n) begin
if(~rst_n) 
	R4 <= 8'd0;
else if (R4_in) 
	R4 <= wrdata?d:A;
end

always@(posedge clk or negedge rst_n ) begin
if(~rst_n) 
	A <= 8'd0;
else if (A_in) begin
	if(co_ab) A <= B ;
	else begin
	case(cnti)
		2'd0: A <= R1;
		2'd1: A <= R2;
		2'd2: A <= R3;
		2'd3: A <= R4;
	endcase
	end
	end
end

always@(posedge clk or negedge rst_n ) begin
if(~rst_n) 
	B <= 8'd0;
else if (B_in) begin
	case(cntj)
		2'd0: B <= R1;
		2'd1: B <= R2;
		2'd2: B <= R3;
		2'd3: B <= R4;
		default:;
	endcase
	end
end


always@(posedge clk,negedge rst_n) begin
if(~rst_n) 
	cnti <= 0;
else if(en_cnti)
	cnti <= cnti + 1'b1;
else if(state==S7&z0)
	cnti <= 2'd0;
end

always@(posedge clk,negedge rst_n) begin
if(~rst_n) 
	cntj <= 0;
else if (state==S1&s)
	cntj <= cnti + 1'b1;
else if (state==S7&z1)
	cntj <= cnti + 2'b10;
else if (en_cntj)
	cntj <= cntj + 1'b1;
else if (state==S7&z0)
	cntj <= 2'd0;
end

assign wrdata = state==S1&~s;
assign co_ab = (A>B); 
assign z1 = cntj==2'b11;
assign z0 = cnti==2'b10;
assign en_cntj = (state==S7&~z1);
assign en_cnti = (state==S7)&(z1)&(~z0);
assign R1_in = (state==S1&~s)|(state==S7&cnti==2'd0)|(state==S5&cntj==2'd0);
assign R2_in = (state==S1&~s)|(state==S7&cnti==2'd1)|(state==S5&cntj==2'd1);
assign R3_in = (state==S1&~s)|(state==S7&cnti==2'd2)|(state==S5&cntj==2'd2);
assign R4_in = (state==S1&~s)|(state==S7&cnti==2'd3)|(state==S5&cntj==2'd3);
assign A_in = (state==S2)|(state==S6);
assign B_in = state==S3;
assign done = state==S8&~s;
assign d1 = state==S8?R1:d1;
assign d2 = state==S8?R2:d2;
assign d3 = state==S8?R3:d3;
assign d4 = state==S8?R4:d4;
endmodule

易错点在于,给出Ain Bin的周期要比给出en_cnti,en_cntj滞后一拍。在状态S7时,转到S2或者S3,这时就要确定给出encnt的信号,在状态S2\S3时,cnt被更新(这一时钟周期开始时,采样到上个周期的encnt有效信号),这时根据encnt可以判断出A\B分别应该写入哪个寄存器的数据。

寄存到R中的周期有,最开始载入S1状态下,以及交换数据的周期S5,S7。

寄存到A中的时钟周期有,进入计算时S2,交换数据周期S6;

寄存到B中的时钟周期有,进入内循环后S3。

下图是ASM图

 

 

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值