HDLbits(3)
60、mux2to1
assign out = sel ? b : a ;
61、mux2to1v
assign out = sel ? b : a;
62、mux9to1v
always @(*)
begin
case(sel)
0: out = a ;
1: out = b ;
2: out = c ;
3: out = d ;
4: out = e ;
5: out = f ;
6: out = g ;
7: out = h ;
8: out = i ;
default:out = 16'hffff;
endcase
end
63、mux256to1
assign out = in[sel] ;
使用输入sel作为in的指针。也可以assign out = in >> sel 。将in向右移sel位,赋值给out。因为out只有一位,所以in的高位会被截去,将sel位赋给out。
64、mux256to1v
assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};
错误写法:assign out = in[selx4+3:selx4]; 这个语句不符合verilog语法规则
其他写法:
assign out = in[sel*4 +: 4];// 从 sel*4 开始,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4]
assign out = in[sel*4+3 -: 4]; // 从 sel*4+3 开始,选择比特序号小于 sel*4+3 的 4 位比特,相当于[sel*4+3:sel*4]
65、hadd
assign {cout,sum} = a + b;
66、full adder
assign {cout,sum} = a+b+cin ;
67、3bit binary adder
assign {cout[0],sum[0]} = a[0] + b[0] + cin ;
assign {cout[1],sum[1]} = a[1] + b[1] + cout[0] ;
assign {cout[2],sum[2]} = a[2] + b[2] + cout[1] ;
68、adder
assign {cout[0],sum[0]} = x[0] + y[0] ;
assign {cout[1],sum[1]} = x[1] + y[1] + cout[0];
assign {cout[2],sum[2]} = x[2] + y[2] + cout[1];
assign {sum[4],sum[3]} = x[3] + y[3] + cout[2];
69、signed addition overflow
assign s = a + b ;
assign overflow = ( a[7] && b[7] && ~s[7] ) || (~a[7] && ~b[7] && s[7]);
有符号数运算的溢出有两种情况。主要是正+正=负和负+负=正。对于这两种情况只需要考虑符号位的变化,即可判断是否发生了溢出。
还有一种办法是从n和n-1位的关系导出。即第n位为符号位,n-1位为数值最高位,这两位进行异或即可得到是否溢出。这个办法在微机原理中讲8086提到比较多。
70、adder100
wire [99:0] cout_in ;
assign {cout_in[0],sum[0]} = a[0] + b[0] + cin ;
generate
genvar i;
for(i=1;i<=99;i=i+1)
begin:add
assign {cout_in[i],sum[i]} = a[i] + b[i] + cout_in[i-1];
end
endgenerate
assign cout = cout_in[99];
71、bcdadd4
wire [3:0] cout_in ;
bcd_fadd add_0(a[3:0],b[3:0],cin,cout_in[0],sum[3:0]);
generate
genvar i ;
for(i=1;i<4;i=i+1)
begin:bcdadd
bcd_fadd add_i(a[4*i+3:4*i],b[4*i+3:4*i],cout_in[i-1],cout_in[i],sum[4*i+3:4*i]);
end
endgenerate
assign cout = cout_in[3];
72、3-variables
assign out = (a==0&&b==0&&c==0)?1'b0 : 1'b1 ;
73、4-variables
assign out = ~b&~c | ~a&~d | b&c&d | a&~b&d ;
74、4-variables
assign out = a | ~b&c ;
卡诺图中d相当于x,可以看作1也可以看作0;
75、4-variables
无法化简
assign out = (~a&b&~c&~d) | (a&~b&~c&~d) | (~a&~b&~c&d) | (a&b&~c&d) | (~a&b&c&d) | (a&~b&c&d) | (~a&~b&c&~d) | (a&b&c&~d);
76、minimum SOP和POS
assign out_sop = c&d | ~a&~b&c ;
assign out_pos = !(~c | b&c&~d | a&~b&c) ;
sop是圈1,pos是圈0得到积之和再取反
77、karnaugh map
assign f = ~x[1]&x[3]|x[1]&x[2]&~x[3] ;
78、karnaugh map
assign f = ~x[1]&x[3] | x[2]&x[3]&x[4] | ~x[2]&~x[4] ;
79、k-map implemented with a multiplexer
assign mux_in = {c&d,~d,1'b0,c|d};
将mux分为四路,化简每路确定每路的输出
80、D flip-flip
always @(posedge clk)
begin
q <= d;
end
81、D flip-flips
reg [7:0] q_out;
always @(posedge clk)
begin
q_out <= d;
end
assign q = q_out;
82、DFF with reset
always@(posedge clk)
begin
if(reset)
q <= 0;
else
q <= d;
end
synchonous同步
83、DFF with reset value
always @(negedge clk)
begin
if(reset)
q <= 8'h34;
else
q <= d;
end
84、DFF with asynchronous reset
always @(posedge clk or posedge areset)
begin
if(areset)
q <= 8'd0;
else
q <= d ;
end
85、DFF with byte enable
always @(posedge clk)
begin
if(!resetn)
q <= 16'h0;
else
begin
case(byteena)
2'b00: begin q <=q;end
2'b01: begin q[15:8]<=q[15:8];q[7:0]<=d[7:0];end
2'b10: begin q[15:8]<=d[15:8];q[7:0]<=q[7:0];end
2'b11: begin q<=d;end
default:q<=16'h0;
endcase
end
end
使能关闭时,对应寄存器值保持不变,而不是输出0;
86、D latch
always @(*)
begin
if(ena)
q = d;
else
q = q;
end
85、DFF
always @(posedge clk or posedge ar)
begin
if(ar)
q <= 0;
else
q<= d ;
end
86、DFF
always @(posedge clk)
begin
if(r)
q <= 0;
else
q<= d;
end
87、DFF + gate
always @(posedge clk)
begin
out <= in ^ out ;
end
88、Mux and DFF
wire D;
assign D = L ? r_in : q_in ;
always @(posedge clk)
begin
Q <= D;
end
89、Mux and DFF
wire D;
always @(*)
begin
case({E,L})
2'b00:D = Q;
2'b10:D = w;
2'b01,2'b11:D = R;
default:D=0;
endcase
end
always @(posedge clk)
begin
Q <= D;
end
90、DFF and gates
reg[2:0] Q;
always@(posedge clk)
begin
Q[0] <= x ^ Q[0];
Q[1] <= x & ~Q[2];
Q[2] <= x | ~Q[2];
end
assign z = ~|Q;
91、caret circuit from truth tabale
always @(posedge clk)
begin
case({j,k})
2'b00: Q <= Q;
2'b01: Q <= 1'b0;
2'b10: Q <= 1'b1;
3'b11: Q <= ~Q ;
endcase
end
92、detect an edge
reg[7:0] in_1,in_2;
always @(posedge clk)
begin
in_1 <= in;
in_2 <= in_1;
end
assign pedge = ~in_2 & in_1 ;
打两拍再进行组合逻辑运算,或者直接在第二拍进行逻辑运算。
reg[7:0] in_1,in_2;
always @(posedge clk)
begin
in_1 <= in;
pedge <= ~in_1 & in;
end
将输入打一拍进行错位,此时若in为1,in_1为0则为上升沿,in为0,in_1为1则为下降沿。
93、detect both edges
reg[7:0] in_1;
always @(posedge clk)
begin
in_1 <= in;
anyedge <= in_1 ^ in ;
end
94、edge capture register
这道题捕获输入下降沿,捕获到下降沿就使对应out为1并保持,除非复位。
reg [31:0] in_1;
wire [31:0] capture;
always @(posedge clk)
begin
in_1 <= in;
end
assign capture = ~in & in_1;//检测下降沿信号
always @(posedge clk)
begin
if(reset)
out <= 32'h0;
else
begin
for(int i=0;i<32;i=i+1)
begin
if(capture[i]==1'b1)
out[i] <= 1'b1;
end
end
end
95、dual-edge triggered flip-flop
本题要求实现同时在时钟上升沿和下降沿进行采样。所以采用两个寄存器分别对时钟上升沿和下降沿进行采样,然后将q看作一根导线,在时钟为高电平时将输出连到上升沿采样寄存器,在时钟为低电平时将输出连接到下降沿采样寄存器
reg q1,q2;
assign q = clk ? q1:q2;
always @(posedge clk)
begin
q1 <= d;
end
always @(negedge clk)
begin
q2 <= d;
end
96、Four-bit binary counter
reg[3:0] counter;
always @(posedge clk)
begin
if(reset)
counter <= 4'b0;
else if(counter == 4'hf)
counter <= 4'b0;
else
counter <= counter + 1;
end
assign q = counter ;
97、Decade counter
reg[3:0] counter;
always @(posedge clk)
begin
if(reset)
counter <= 4'b0;
else if(counter == 4'd9)
counter <= 4'b0;
else
counter <= counter + 1;
end
assign q = counter ;
98、Decade counter again
reg[3:0] counter;
always @(posedge clk)
begin
if(reset)
counter <= 4'd1;
else if(counter == 4'd10)
counter <= 4'd1;
else
counter <= counter + 1;
end
assign q = counter ;
99、slow decade counter
reg [3:0] counter;
always @(posedge clk)
begin
if(reset)
counter <= 4'd0;
else
begin
if(!slowena)
counter <= counter;
else if(counter == 4'd9)
counter <= 4'd0;
else
counter <= counter + 1;
end
end
assign q = counter ;
100、counter 1-12
assign c_enable = enable ;
assign c_load = reset | (Q == 4'd12 & enable == 1);
assign c_d = 4'd1;
count4 the_counter (clk, c_enable, c_load, c_d ,Q );
本题主要是对给定的计数器再包一层,加入一些控制信号使其成为1-12计数器。思想是在检测到其需要复位或者计数到12时,使载入信号有效,这时载入1。
101、counter100
wire[3:0] Q0,Q1,Q2;
assign c_enable[0] = 1'b1;
assign c_enable[1] = (Q0==4'd9) ? 1'b1 : 1'b0;
assign c_enable[2] = ((Q1==4'd9) &&(Q0 == 4'd9) ) ? 1'b1 : 1'b0;
always @(*)
begin
if(reset)
OneHertz = 1'b0;
else if(Q2 == 4'd9 && Q1 == 4'd9 && Q0 == 4'd9)
OneHertz = 1'b1;
else
OneHertz = 1'b0;
end
bcdcount counter0 (clk, reset, c_enable[0],Q0/*, ... */);
bcdcount counter1 (clk, reset, c_enable[1],Q1/*, ... */);
bcdcount counter2 (clk, reset, c_enable[2],Q2/*, ... */);
注意要在前两级计数器计到99才开启第三级计数器,条件判断是(Q1==4'd9) &&(Q0 == 4'd9),如果只有Q1 == 4‘d9,那么判断的是计到90。
102、4-digit decimal counter
reg [3:0]count0,count1,count2,count3;
always @(posedge clk)
begin
if(reset)
count0 <= 0;
else if(count0 == 4'd9)
count0 <= 4'd0;
else
count0 <= count0 + 1;
end
always @(posedge clk)
begin
if(reset)
count1<= 0;
else if(count1== 4'd9 && count0 == 4'd9)
count1<= 4'd0;
else if(count0 == 4'd9)
count1<= count1+ 1;
end
always @(posedge clk)
begin
if(reset)
count2<= 0;
else if(count2== 4'd9 && count1== 4'd9 && count0 == 4'd9)
count2<= 4'd0;
else if(count0 == 4'd9 && count1 == 4'd9)
count2<= count2+ 1;
end
always @(posedge clk)
begin
if(reset)
count3<= 0;
else if(count3 == 4'd9 && count2== 4'd9 && count1== 4'd9 && count0 == 4'd9)
count3<= 4'd0;
else if(count2 == 4'd9 && count0 == 4'd9 && count1 == 4'd9)
count3<= count3+ 1;
end
assign ena[1] = (count0 == 4'd9) ? 1'b1:1'b0;
assign ena[2]= (count0 == 4'd9 && count1 == 4'd9) ? 1'b1:1'b0;
assign ena[3]= (count0 == 4'd9 && count1 == 4'd9 && count2 == 4'd9) ? 1'b1:1'b0;
assign q[15:0] = {count3,count2,count1,count0};
103、12-hour clock
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
reg [7:0] h;
reg p;
reg [7:0] s;
reg [7:0] m;
wire ena_m;
wire ena_h;
assign ena_m = ena && (s == 8'h59);
assign ena_h = ena && (s == 8'h59) && (m == 8'h59);
count60 count_s(clk,reset,ena,s);
count60 count_m(clk,reset,ena_m,m);
always @(posedge clk)
begin
if(reset)
p <= 1'b0;
else if(h == 8'h11&& s == 8'h59 && m == 8'h59)
p <= ~p;
else
p <= p;
end
always @(posedge clk)
begin
if(reset)
h <= 8'h12;
else if(!ena_h)
h <= h;
else if(h == 8'h12 && s == 8'h59 && m == 8'h59)
h <= 8'h1;
else if(s == 8'h59 && m == 8'h59)
begin
h[3:0] <= h[3:0] + 4'h1;
if(h[3:0]==4'h9)
begin
h[7:4] <= h[7:4] + 4'h1;
h[3:0] <= 4'h0;
end
end
end
assign pm = p;
assign hh = h;
assign mm = m;
assign ss = s;
endmodule
module count60(input clk,input reset,input ena,output reg [7:0]count);
always @(posedge clk)
begin
if(reset)
count <= 8'h0;
else if(~ena)
count <= count;
else if(count == 8'h59)
count <= 8'h0;
else
begin
count[3:0] <= count[3:0] + 4'h1;
if(count[3:0] == 4'h9 )
begin
count[7:4] <= count[7:4] + 4'h1;
count[3:0] <= 4'h0;
end
end
end
endmodule
注意题目,使用BCD码表示。
104、4-bit shift register
always @(posedge clk or posedge areset)
begin
if(areset)
q <= 4'h0;
else
begin
if(load)
q <= data;
else if(ena)
q <= {1'b0,q[3],q[2],q[1]};
else
q <= q;
end
end
105、left/right rotator
always @(posedge clk)
begin
if(load)
q <= data;
else
begin
case(ena)
2'b01:q<={q[0],q[99:1]};
2'b10:q<={q[98:0],q[99]};
default:q <= q;
endcase
end
end
106、left/right arithmetic shift by 1 or 8
always @(posedge clk)
begin
if(load)
q <= data;
else if(ena)
begin
case(amount)
2'b00:q <= {q[62:0],1'b0};
2'b01:q <= {q[55:0],8'b0};
2'b10:q <= {q[63],q[63:1]};
2'b11:q <= {{8{q[63]}},q[63:8]};
endcase
end
end
107、5-bit LFSR
always @(posedge clk )
begin
if(reset)
q <= 5'h1;
else
begin
q[4] <= q[0] ^ 1'b0;
q[3] <= q[4];
q[2] <= q[3] ^ q[0] ;
q[1] <= q[2] ;
q[0] <= q[1] ;
end
end
108、3-bit LFSR
reg[2:0] Q;
wire[2:0]R;
wire[2:0]D;
wire L;
wire clk;
assign D[0] = L ? R[0] : Q[2];
assign D[1] = L ? R[1] : Q[0];
assign D[2] = L ? R[2] : (Q[1]^Q[2]);
always @(posedge clk)
begin
Q[0] <= D[0];
Q[1] <= D[1];
Q[2] <= D[2];
end
assign R = SW;
assign {L,clk} = KEY;
assign LEDR = Q;
109、32-bit LFSR
always @(posedge clk)
begin
if(reset)
q <= 32'h1;
else
q <= {q[0],q[31:23],q[22]^q[0],q[21:3],q[2]^q[0],q[1]^q[0]};
end
110、shift register
reg [3:0] q;
always @(posedge clk)
begin
if(!resetn)
q <= 4'h0;
else
begin
q[0] <= in;
q[1] <= q[0];
q[2] <= q[1];
q[3] <= q[2];
end
end
assign out = q[3] ;
111、shift register
wire [3:0] w_input = {KEY[3],LEDR[3],LEDR[2],LEDR[1]};
generate
genvar i;
for(i=0;i<4;i=i+1) begin:muxdff
MUXDFF (
.clk(KEY[0]),
.w(w_input[i]),
.R(SW[i]),
.E(KEY[1]),
.L(KEY[2]),
.Q(LEDR[i])
);
end
endgenerate
endmodule
module MUXDFF (input clk,input w,R,E,L,output reg Q);
always @(posedge clk)
begin
case({E,L})
2'b00 : Q <= Q;
2'b01: Q <= R;
2'b10 : Q <= w;
2'b11: Q <= R;
endcase
end
endmodule
112、3-input LUT
reg [0:7] Q;
always @(posedge clk)
begin
if(enable)
Q <= {S,Q[0:6]};
end
always @(*)
begin
case({A,B,C})
3'b000 : Z = Q[0];
3'b001 : Z = Q[1];
3'b010 : Z = Q[2];
3'b011 : Z = Q[3];
3'b100 : Z = Q[4];
3'b101 : Z = Q[5];
3'b110 : Z = Q[6];
3'b111 : Z = Q[7];
endcase
end
需要注意输入S填充到Q[0],然后向右移位。
113、Rule 90
always @(posedge clk)
begin
if(load)
q <= data;
else
q <= {1'b0,q[511:1]} ^ {q[510:0],1'b0};
end
q的每一位下一状态是当前状态的两个相邻元素异或得到;
114、rule 110
always @(posedge clk)
begin
if(load)
q <= data;
else
q <= (q ^ {q[510:0],1'b0}) | ((~{1'b0,q[511:1]})&q);
end
把真值表进行卡诺图化简得到表达式,注意B非C+BC非是BC的异或
115、conwaylife
reg [3:0] count;
integer i;
always @(posedge clk)begin
if(load)begin
q <= data;
end
else begin
for(i=0;i<256;i++)begin
if(i == 0)begin
count = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];
end
else if(i == 15)begin
count = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];
end
else if(i == 240)begin
count = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];
end
else if(i == 255)begin
count = q[238] + q[239] + q[224] + q[254] + q[240] + q[15] + q[0] + q[14];
end
else if( i>0 && i<15)begin
count = q[239+i]+q[240+i]+q[241+i]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];
end
else if(i>240 && i<255)begin
count = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i-239]+q[i-240]+q[i-241];
end
else if( i%16 == 0)begin
count = q[i-1]+q[i-16]+q[i-15]+q[i+15]+q[i+1]+q[i+31]+q[i+16]+q[i+17];
end
else if(i % 16 == 15)begin
count = q[i-17]+q[i-16]+q[i-31]+q[i-1]+q[i-15]+q[i+15]+q[i+16]+q[i+1];
end
else begin
count = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];
end
case(count)
4'd2:q[i] <= q[i];
4'd3:q[i] <= 1'b1;
default:q[i] <= 1'b0;
endcase
end
end
end
116、simple FSM 1
状态机最好采用三段式写法:状态跳转逻辑、状态触发器实现、输出逻辑确定
parameter A=0, B=1;
reg state, next_state;
always @(*) begin // This is a combinational always block
// State transition logic
case (state)
A : next_state = in ? A : B;
B : next_state = in ? B : A;
endcase
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if(areset)
state <= B;
else
state <= next_state;
end
// Output logic
// assign out = (state == ...);
assign out = (state == B);
107、simple FSM 1
parameter A=0, B=1;
reg state, next_state;
always @(*) begin // This is a combinational always block
// State transition logic
case (state)
A : next_state = in ? A : B;
B : next_state = in ? B : A;
endcase
end
always @(posedge clk) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if(reset)
state <= B;
else
state <= next_state;
end
// Output logic
// assign out = (state == ...);
assign out = (state == B);
108、simple FSM 2
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
case(state)
ON : next_state = k ? OFF : ON;
OFF: next_state = j ? ON : OFF;
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)
state <= OFF;
else
state <= next_state;
end
// Output logic
// assign out = (state == ...);
assign out = (state == ON) ;
109、simple FSM 2
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
case(state)
ON : next_state = k ? OFF : ON;
OFF: next_state = j ? ON : OFF;
endcase
end
always @(posedge clk) begin
// State flip-flops with asynchronous reset
if(reset)
state <= OFF;
else
state <= next_state;
end
// Output logic
// assign out = (state == ...);
assign out = (state == ON) ;
110、simple state transition 3
always @(*)
begin
case(state)
A : next_state = in ? B : A;
B : next_state = in ? B : C;
C : next_state = in ? D : A;
D : next_state = in ? B : C;
endcase
end
assign out = (state == D) ;
111、simple one-hot state transition
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = (state[A]&~in) | (state[C] & ~in);
assign next_state[B] = (state[A]&in) | (state[D]&in) | (state[B]&in);
assign next_state[C] = (state[B]&~in) | (state[D]&~in);
assign next_state[D] = (state[C]&in);
// Output logic:
assign out = (state[D]);
根据真值表,得到每一位置1的条件
112、simple FSM 3
异步复位
parameter A = 0, B = 1 , C = 2 , D = 3;
reg [1:0] state,next_state;
always @(*)
begin
case(state)
A : next_state = in ? B : A ;
B : next_state = in ? B : C ;
C : next_state = in ? D : A ;
D : next_state = in ? B : C ;
endcase
end
always @(posedge clk or posedge areset)
begin
if(areset)
state <= A ;
else
state <= next_state;
end
assign out = (state == D);
113、simple FSM 3
同步复位
parameter A = 0, B = 1 , C = 2 , D = 3;
reg [1:0] state,next_state;
always @(*)
begin
case(state)
A : next_state = in ? B : A ;
B : next_state = in ? B : C ;
C : next_state = in ? D : A ;
D : next_state = in ? B : C ;
endcase
end
always @(posedge clk )
begin
if(reset)
state <= A ;
else
state <= next_state;
end
assign out = (state == D);
114、design a moore fsm
reg [3:1] state ,next_state;
reg flag,next_flag;
wire [3:1] fr;
assign {fr3,fr2,fr1} = fr;
assign next_state = s;
always @(*)
begin
case(state)
3'b111: fr = 3'b0;
3'b011: fr = 3'b001;
3'b001: fr = 3'b011;
3'b000: fr = 3'b111;
default: fr = 3'b000;
endcase
end
always @(*)
begin
if(s == state)
next_flag = flag;
else if(s < state || s == 0)
next_flag = 1'b1 ;
else
next_flag = 1'b0;
end
always @(posedge clk )
begin
if(reset) begin
state <= 0;
flag <= 1'b1;
end
else begin
state <= next_state;
flag <= next_flag;
end
end
assign dfr = (flag == 1'b1);
115、Lemmings1
parameter LEFT = 1 , RIGHT = 0;
reg state,next_state;
always @(*)
begin
case (state)
RIGHT : next_state = bump_right ? LEFT : RIGHT;
LEFT : next_state = bump_left ? RIGHT : LEFT;
endcase
end
always @(posedge clk or posedge areset)
begin
if(areset)
state <= LEFT;
else
state <= next_state;
end
assign walk_left = (state == LEFT) ;
assign walk_right = (state == RIGHT) ;
116、Lemmings 2
parameter LEFT = 1 , RIGHT = 0 , FALL = 2;
reg [1:0] state,next_state;
reg walk;
always @(*)
begin
if(ground == 1'b1)
case (state)
RIGHT : next_state = bump_right ? LEFT : RIGHT;
LEFT : next_state = bump_left ? RIGHT : LEFT;
FALL : next_state = walk ;
endcase
else
next_state = FALL ;
end
always @(posedge clk or posedge areset)
begin
if(areset)
state <= LEFT;
else
state <= next_state;
end
always @(posedge clk)
begin
case(state)
RIGHT : walk <= 1'b0;
LEFT : walk <= 1'b1;
default: walk <= walk;
endcase
end
assign walk_left = (state == LEFT) ;
assign walk_right = (state == RIGHT) ;
assign aaah = (state == FALL) ;
117、Lemmings 3
localparam left = 0;
localparam right = 1;
localparam left_dig = 2;
localparam right_dig = 3;
localparam left_fall = 4;
localparam right_fall = 5;
reg[2:0] state, next_state;
reg[3:0] out;
//state
always@(posedge clk or posedge areset) begin
if(areset)
state <= left;
else
state <= next_state;
end
//transition
always@(*) begin
case(state)
left:next_state=ground?(dig?left_dig:(bump_left?right:left)):left_fall;
right:next_state=ground?(dig?right_dig:(bump_right?left:right)):right_fall;
left_dig:next_state=ground?left_dig:left_fall;
right_dig:next_state=ground?right_dig:right_fall;
left_fall:next_state=ground?left:left_fall;
right_fall:next_state=ground?right:right_fall;
endcase
end
//out
always@(posedge clk or posedge areset) begin
if(areset)
out <= 4'b1000;
else
case(next_state)
left: out <= 4'b1000;
left_dig: out <= 4'b0001;
left_fall: out <= 4'b0010;
right: out <= 4'b0100;
right_dig: out <= 4'b0001;
right_fall: out <= 4'b0010;
endcase
end
assign {walk_left, walk_right, aaah, digging} = out;
根据状态转移图按照三段式写法,条理更清楚
118、Lemmings 4
localparam left = 0;
localparam right = 1;
localparam left_dig = 2;
localparam right_dig = 3;
localparam left_fall = 4;
localparam right_fall = 5;
localparam over = 6;
reg[2:0] state, next_state;
reg[3:0] out;
reg[7:0] cnt;
always@(posedge clk or posedge areset) begin
if(areset)
state <= left;
else
state <= next_state;
end
always@(*) begin
case(state)
left:next_state=ground?(dig?left_dig:(bump_left?right:left)):left_fall;
right:next_state=ground?(dig?right_dig:(bump_right?left:right)):right_fall;
left_dig:next_state=ground?left_dig:left_fall;
right_dig:next_state=ground?right_dig:right_fall;
left_fall:next_state=ground?((cnt>=5'd21)?over:left):left_fall;
right_fall:next_state=ground?((cnt>=5'd21)?over:right):right_fall;
over:next_state=over;
endcase
end
always@(posedge clk or posedge areset) begin
if(areset) begin
out <= 4'b1000;
end
else
case(next_state)
left:begin
out <= 4'b1000;
cnt <= 0;
end
right:begin
out <= 4'b0100;
cnt <= 0;
end
left_dig:begin
out <= 4'b0001;
cnt <= 0;
end
right_dig:begin
out <= 4'b0001;
cnt <= 0;
end
left_fall:begin
out <= 4'b0010;
cnt = cnt + 1;
end
right_fall:begin
out <= 4'b0010;
cnt = cnt + 1;
end
over:out <= 4'b0000;
endcase
end
assign {walk_left, walk_right, aaah, digging} = out;
119、ONT-HOT fsm
parameter S0 = 4'd0, S1 = 4'd1, S2 = 4'd2, S3 = 4'd3, S4 = 4'd4;
parameter S5 = 4'd5, S6 = 4'd6, S7 = 4'd7, S8 = 4'd8, S9 = 4'd9;
assign next_state[S0] = ~in & (state[S0] | state[S1] | state[S2] | state[S3] | state[S4] | state[S7] | state[S8] | state[S9]);
assign next_state[S1] = in & (state[S0] | state[S8] | state[S9]);
assign next_state[S2] = in & state[S1];
assign next_state[S3] = in & state[S2];
assign next_state[S4] = in & state[S3];
assign next_state[S5] = in & state[S4];
assign next_state[S6] = in & state[S5];
assign next_state[S7] = in & (state[S6] | state[S7]);
assign next_state[S8] = ~in & state[S5];
assign next_state[S9] = ~in & state[S6];
assign out1 = state[S8] | state[S9];
assign out2 = state[S7] | state[S9];
对照着转移图直接写
120、PS/2 packet parser
parameter S1=0,S2=1,S3=2,S4=3;
reg [2:0] state,next_state;
always @(posedge clk)
begin
if(reset)
state <= S1;
else
state <= next_state;
end
always @(*)
begin
case(state)
S1 : next_state = in[3] ? S2 : S1;
S2 : next_state = S3;
S3 : next_state = S4;
S4 : next_state = in[3] ? S2 : S1;
endcase
end
assign done = (state == S4) ;
121、PS/2 packet parser and datapath
parameter S1=0,S2=1,S3=2,S4=3;
reg [2:0] state,next_state;
reg [23:0] out;
always @(posedge clk)
begin
if(reset)
state <= S1;
else
state <= next_state;
end
always @(*)
begin
case(state)
S1 :begin
next_state = in[3] ? S2 : S1;
end
S2 :begin
next_state = S3;
end
S3 : begin
next_state = S4;
end
S4 :begin
next_state = in[3] ? S2 : S1;
end
endcase
end
always @(posedge clk)
begin
case (state)
S1 : out[23:16] <= (next_state == S2) ? in : 8'h0;
S2 : out[15:8] <= in;
S3 : out[7:0] <= in;
S4 : out[23:16] <= (next_state == S2) ? in : 8'h0;
endcase
end
assign done = (state == S4) ;
assign out_bytes = done ? out : 8'h0;
122、serial receiver
parameter START=0,BIT1=1,BIT2=2,BIT3=3,BIT4=4,BIT5=5,BIT6=6,BIT7=7,BIT8=8,STOP=9,WAIT=10,IDLE=11;
reg[3:0]state,next_state;
always @(posedge clk)
begin
if(reset)
state <= IDLE;
else
state <= next_state;
end
always @(*)
begin
case(state)
IDLE : next_state = in ? IDLE : START;
START : next_state = BIT1;
BIT1 : next_state = BIT2;
BIT2 : next_state = BIT3;
BIT3 : next_state = BIT4;
BIT4 : next_state = BIT5;
BIT5 : next_state = BIT6;
BIT6 : next_state = BIT7;
BIT7 : next_state = BIT8;
BIT8 : next_state = in ? STOP : WAIT;
WAIT: next_state = in ? IDLE : WAIT;
STOP : next_state = in ? IDLE : START;
default:next_state <= IDLE;
endcase
end
assign done = (state == STOP);
123、serial receiver and datapath
parameter START=0,BIT1=1,BIT2=2,BIT3=3,BIT4=4,BIT5=5,BIT6=6,BIT7=7,BIT8=8,STOP=9,WAIT=10,IDLE=11;
reg[3:0]state,next_state;
reg[7:0] out;
always @(posedge clk)
begin
if(reset)
state <= IDLE;
else
state <= next_state;
end
always @(*)
begin
case(state)
IDLE : next_state = in ? IDLE : START;
START : next_state = BIT1;
BIT1 : next_state = BIT2;
BIT2 : next_state = BIT3;
BIT3 : next_state = BIT4;
BIT4 : next_state = BIT5;
BIT5 : next_state = BIT6;
BIT6 : next_state = BIT7;
BIT7 : next_state = BIT8;
BIT8 : next_state = in ? STOP : WAIT;
WAIT: next_state = in ? IDLE : WAIT;
STOP : next_state = in ? IDLE : START;
default:next_state <= IDLE;
endcase
end
always @(posedge clk)
begin
case(state)
START:out[0] <= in;
BIT1: out[1] <= in;
BIT2: out[2] <= in;
BIT3: out[3] <= in;
BIT4: out[4] <= in;
BIT5: out[5] <= in;
BIT6: out[6] <= in;
BIT7: out[7] <= in;
//BIT8: out[7] <= in;
default:out <= out;
endcase
end
assign done = (state == STOP);
assign out_byte = done ? out : 8'b0;
注意对应好状态于当前输入的关系
124、serial receiver with parity checking
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
parameter IDLE = 3'd0;
parameter DATA = 3'd1;
parameter CHECK = 3'd2;
parameter STOP = 3'd3;
parameter ERROR = 3'd4;
reg [2 : 0] curr_state;
reg [2 : 0] next_state;
reg [3 : 0] cnt;
reg [7 : 0] out;
reg check;
wire odd;
wire start;
//transition
always@(*)
begin
start = 0;
case(curr_state)
IDLE : begin
next_state = in ? IDLE : DATA;
start=1;
end
DATA : begin
next_state = (cnt == 8) ? CHECK : DATA;
end
CHECK: begin
next_state = in ? STOP : ERROR;
end
STOP : begin
next_state = in ? IDLE : DATA;
start = 1;
end
ERROR: begin
next_state = in ? IDLE : ERROR;
end
endcase
end
//state
always@(posedge clk)
begin
if(reset)
curr_state <= IDLE;
else
curr_state <= next_state;
end
//cnt
always@(posedge clk)
begin
if(reset)
cnt <= 0;
else begin
case(curr_state)
DATA: cnt <= cnt + 1'b1;
default: cnt <= 0;
endcase
end
end
//out
always@(posedge clk)
begin
if(reset)
out <= 8'd0;
else begin
case(next_state)
DATA: out <= {in, out[7 : 1]};
endcase
end
end
//check
always@(posedge clk)
begin
if(reset)
check <= 1'b0;
else
check <= odd;
end
assign out_byte = out;
assign done = check & (curr_state == STOP);
parity parity_inst(
.clk(clk),
.reset(reset | start),
.in(in),
.odd(odd));
endmodule
125、sequence recognition
parameter none=4'd0;
parameter one=4'd1;
parameter two=4'd2;
parameter three=4'd3;
parameter four=4'd4;
parameter five=4'd5;
parameter six=4'd6;
parameter error=4'd7;
parameter discard=4'd8;
parameter flag_=4'd9;
reg [3:0] state;
reg [3:0] next_state;
always@(posedge clk)
if(reset)
state<=none;
else
state<=next_state;
always@(*)
case(state)
none :next_state=in?one:none;
one :next_state=in?two:none;
two :next_state=in?three:none;
three :next_state=in?four:none;
four :next_state=in?five:none;
five :next_state=in?six:discard;
six :next_state=in?error:flag_;
error :next_state=in?error:none;
discard:next_state=in?one:none;
flag_ :next_state=in?one:none;
endcase
assign disc = state == discard;
assign flag = state == flag_;
assign err = state == error;
126、Desgin a Mealy FSM
parameter IDLE=0,ONE=1,TWO=2;
reg[1:0] state,next_state;
always @(posedge clk or negedge aresetn)
begin
if(~aresetn)
state <= IDLE;
else
state <= next_state;
end
always @(*)
begin
case(state)
IDLE : begin
next_state = x ? ONE : IDLE;
z = 1'b0;end
ONE : begin
next_state = x ? ONE : TWO;
z = 1'b0;end
TWO: begin
next_state = x ? ONE : IDLE;
z = x ? 1'b1 : 1'b0;end
endcase
end
127、Q5a
这道题假设输入都是负数,对输入作按位取反加一操作就行。对于源码和补码的区出现在第一个1,因为第一个1取反后变为0,此时进位到此为止。
.
parameter A=0,B=1,C=2;
reg[1:0] state,next_state;
always @(posedge clk or posedge areset)
begin
if(areset)
state <= A;
else
state <= next_state;
end
always @(*)
begin
case (state)
A : next_state = x ? B : A;
B : next_state = x ? C : B;
C : next_state = x ? C : B;
endcase
end
assign z = (state == B) ;
128、Q5b
parameter A=0,B=1;
reg[1:0] state,next_state;
always @(posedge clk or posedge areset)
begin
if(areset)
state <= A;
else
state <= next_state;
end
always @(*)
begin
case (state)
A : next_state = x ? B : A;
B : next_state = B;
endcase
end
assign z = state == A ? x:~x ;
129、Q3A
reg [3:0] state;
reg [3:0] nxt_state;
wire w_shft_ena;
reg[1:0] w_cntr;
localparam A = 0;
localparam B = 1;
localparam B1 = 2;
localparam B2 = 4;
// State transition logic (combinational)
always @(*) begin
case (state)
A:begin
if(s)
nxt_state = B;
else
nxt_state = A;
end
B:begin
nxt_state = B1;
end
B1:begin
nxt_state = B2;
end
B2:begin
nxt_state = B;
end
default: begin
nxt_state = A;
end
endcase
end
// State flip-flops (sequential)
always @(posedge clk ) begin
if(reset)
state <= A;
else begin
state <= nxt_state;
end
end
always @(posedge clk ) begin
if(reset)
w_cntr <= 2'b0;
else if(state == B)begin
w_cntr <= w;
end
else if(state == B1 || state == B2)begin
w_cntr <= w_cntr + w;
end
end
assign z = state == B && w_cntr == 2 ? 1'b1 : 1'b0;
130、Q3B
reg [2:0] state;
reg [2:0] nxt_state;
localparam IDLE = 3'd0;
localparam s_1 = 3'd1;
localparam s_10 = 3'd2;
localparam s_11 = 3'd3;
localparam s_100 = 3'd4;
// State transition logic (combinational)
always @(*) begin
case (state)
IDLE:begin
if(x)
nxt_state = s_1;
else
nxt_state = IDLE;
end
s_1:begin
if(x)
nxt_state = s_100;
else
nxt_state = s_1;
end
s_10:begin
if(x)
nxt_state = s_1;
else
nxt_state = s_10;
end
s_11:begin
if(x)
nxt_state = s_10;
else
nxt_state = s_1;
end
s_100:begin
if(x)
nxt_state =s_100;
else
nxt_state = s_11;
end
default: begin
nxt_state = IDLE;
end
endcase
end
// State flip-flops (sequential)
always @(posedge clk ) begin
if(reset)
state <= IDLE;
else begin
state <= nxt_state;
end
end
assign z = state >= s_11;
131、Q3C
本题将当前状态作为输入,只需要规定出状态跳转逻辑即可,用输入来触发跳转,不需要时钟
reg [2:0] state;
reg [2:0] nxt_state;
localparam IDLE = 3'd0;
localparam s_1 = 3'd1;
localparam s_10 = 3'd2;
localparam s_11 = 3'd3;
localparam s_100 = 3'd4;
assign state = y;
// State transition logic (combinational)
always @(*) begin
case (state)
IDLE:begin
if(x)
nxt_state = s_1;
else
nxt_state = IDLE;
end
s_1:begin
if(x)
nxt_state = s_100;
else
nxt_state = s_1;
end
s_10:begin
if(x)
nxt_state = s_1;
else
nxt_state = s_10;
end
s_11:begin
if(x)
nxt_state = s_10;
else
nxt_state = s_1;
end
s_100:begin
if(x)
nxt_state =s_100;
else
nxt_state = s_11;
end
default: begin
nxt_state = IDLE;
end
endcase
end
assign Y0 = nxt_state[0] ;
assign z = state >= s_11;
132、Q6b
注意题目要求的是输出Y2的次态而不是现态
wire [2:0] state = y;
reg [2:0] nxt_state;
localparam sA = 3'd0;
localparam sB = 3'd1;
localparam sC = 3'd2;
localparam sD = 3'd3;
localparam sE = 3'd4;
localparam sF = 3'd5;
// State transition logic (combinational)
always @(*) begin
case (state)
sA:begin
if(w)
nxt_state = sA;
else
nxt_state = sB;
end
sB:begin
if(w)
nxt_state = sD;
else
nxt_state = sC;
end
sC:begin
if(w)
nxt_state = sD;
else
nxt_state = sE;
end
sD:begin
if(w)
nxt_state = sA;
else
nxt_state = sF;
end
sE:begin
if(w)
nxt_state = sD;
else
nxt_state = sE;
end
sF:begin
if(w)
nxt_state = sD;
else
nxt_state = sC;
end
default: begin
nxt_state = sA;
end
endcase
end
assign Y2 = nxt_state[1];
132、Q6c
assign Y2 = ~w & y[1] ;
assign Y4 = (w & y[2])|(w & y[3])|(w & y[5])|(w & y[6]);
133、Q6
reg [5:0] state;
reg [5:0] nxt_state;
localparam sA = 6'd1;
localparam sB = 6'd2;
localparam sC = 6'd4;
localparam sD = 6'd8;
localparam sE = 6'd10;
localparam sF = 6'd20;
// State transition logic (combinational)
always @(*) begin
nxt_state[0] <= w ? state[0] || state[3] : 1'b0;
nxt_state[1] <= w ? 1'b0 : state[0];
nxt_state[2] <= w ? 1'b0 : state[5] || state[1];
nxt_state[3] <= w ? state[1] || state[2] || state[4] || state[5]: 1'b0;
nxt_state[4] <= w ? 1'b0 : state[4] || state[2];
nxt_state[5] <= w ? 1'b0 : state[3];
end
always @(posedge clk ) begin
if(reset)
state <= sA;
else begin
state <= nxt_state;
end
end
assign z = state[4] || state[5];
134、Q2a
reg [6 : 1] curr_state;
reg [6 : 1] next_state;
parameter A = 1;
parameter B = 2;
parameter C = 3;
parameter D = 4;
parameter E = 5;
parameter F = 6;
always@(posedge clk)
begin
if(reset)
curr_state <= A;
else
curr_state <= next_state;
end
always@(*)
begin
next_state[A] = (curr_state[A] & ~w) || (curr_state[D] & ~w);
next_state[B] = (curr_state[A] & w);
next_state[C] = (curr_state[B] & w) || (curr_state[F] & w);
next_state[D] = (curr_state[B] & ~w) || (curr_state[C] & ~w)
|| (curr_state[E] & ~w) || (curr_state[F] & w);
next_state[E] = (curr_state[C] & w) || (curr_state[E] & w);
next_state[F] = (curr_state[D] & w);
end
assign z = curr_state[E] | curr_state[F];
135、Q2b
wire [6 : 1] curr_state = y[5 : 0];
reg [6 : 1] next_state;
parameter A = 1;
parameter B = 2;
parameter C = 3;
parameter D = 4;
parameter E = 5;
parameter F = 6;
always@(*)
begin
next_state[A] = (curr_state[A] & ~w) || (curr_state[D] & ~w);
next_state[B] = (curr_state[A] & w);
next_state[C] = (curr_state[B] & w) || (curr_state[F] & w);
next_state[D] = (curr_state[B] & ~w) || (curr_state[C] & ~w)
|| (curr_state[E] & ~w) || (curr_state[F] & ~w);
next_state[E] = (curr_state[C] & w) || (curr_state[E] & w);
next_state[F] = (curr_state[D] & w);
end
assign Y1 = next_state[B];
assign Y3 = next_state[D];
136、Q2a
wire [2:0] ri = r;
wire [2:0] go;
reg [3:0] state;
reg [3:0] nxt_state;
localparam sidle = 0;
localparam sd1 = 1;//devive 1
localparam sd2 = 2;
localparam sd3 = 3;
// State transition logic (combinational)
always @(*) begin
nxt_state[sidle] <= (state[sidle] && ~(|ri))
|| (state[sd1] && ~ri[0])
|| (state[sd2] && ~ri[1])
|| (state[sd3] && ~ri[2]);
nxt_state[sd1 ] <= (state[sidle] && ri[0])
|| (state[sd1 ] && ri[0]);
nxt_state[sd2 ] <= (state[sidle] && ~ri[0] && ri[1])
|| (state[sd2 ] && ri[1]);
nxt_state[sd3 ] <= (state[sidle] && ~ri[0] && ~ri[1] && ri[2])
|| (state[sd3 ] && ri[2]);
end
// State flip-flops (sequential)
always @(posedge clk ) begin
if(~resetn)
state <= 4'b1;
else begin
state <= nxt_state;
end
end
//output logic
assign go[0] = state[sd1 ];
assign go[1] = state[sd2 ];
assign go[2] = state[sd3 ];
assign g = go;
137、Q2b
本道题要求复位的下一时钟输出f,可以理解为两状态状态机。然后检测x为101又是一个状态机。在检测完成后,进入检测y的状态机。
因为y要检测两个时钟周期,所以加上idle状态即是三个状态。
localparam FSM_W = 10;
localparam FSM_W1 = FSM_W - 1'b1;
reg [FSM_W1:0] state;
reg [FSM_W1:0] nxt_state;
localparam IDLE = 0;
localparam AFT_RST = 1;
localparam STRT_X_MNT= 2;
localparam X_1 = 3;
localparam X_0 = 4;
localparam X_10 = 5;
localparam X_101 = 6;
localparam Y_S0 = 7;
localparam G_O0 = 8;
localparam G_O1 = 9;
// State transition logic (combinational)
always @(*) begin
nxt_state[IDLE ] = 1'b0; // never reach for nxt_state
nxt_state[AFT_RST] = (state[IDLE ]);
nxt_state[STRT_X_MNT] = (state[AFT_RST]);
nxt_state[X_1 ] = (state[STRT_X_MNT] && x) || (state[X_1 ] && x) || (state[X_0 ] && x);
nxt_state[X_0 ] = (state[STRT_X_MNT] && ~x) || (state[X_10 ] && ~x) || (state[X_0 ] && ~x);
nxt_state[X_10 ] = (state[X_1 ] && ~x);
nxt_state[X_101 ] = (state[X_10 ] && x);
nxt_state[Y_S0 ] = (state[X_101 ] && ~y);
nxt_state[G_O0 ] = (state[Y_S0 ] && ~y) || state[G_O0 ];
nxt_state[G_O1 ] = (state[Y_S0 ] && y) || (state[X_101 ] && y) || state[G_O1 ];
end
// State flip-flops (sequential)
always @(posedge clk) begin
if(~resetn)
state <= 'b1; //IDLE
else begin
state <= nxt_state;
end
end
//output logic
assign f = state[AFT_RST];
assign g = (state[X_101] || state[G_O1] || state[Y_S0]) ? 1'b1 : 1'b0;
138、4-bit shift register and down counter
reg [3:0]shift;
always @(posedge clk)
begin
if(shift_ena)
shift <= {shift[2:0],data};
else if(count_ena)
shift <= shift - 1;
else
shift <= shift;
end
assign q = shift;
139、FSM:sequence 1101 recognizer
reg [2:0] state,next_state;
parameter idle=0,s1=1,s11=2,s110=3,s1101=4;
always @(posedge clk)
begin
if(reset)
state <= idle;
else
state <= next_state;
end
always @(*)
begin
case(state)
idle : next_state = data ? s1 : idle;
s1 : next_state = data ? s11: idle;
s11 : next_state = data ? s11: s110;
s110 : next_state = data ? s1101 : idle;
s1101: next_state = s1101;
default : next_state = idle;
endcase
end
assign start_shifting = (state == s1101) ;
140、FSM:Enable shift register
parameter idle=0,s0=1,s1=2,s2=3,s3=4;
reg [2:0] state,next_state;
always @(posedge clk)
begin
if(reset)
state <= s0;
else
state <= next_state;
end
always @(*)
begin
case (state)
idle : next_state = idle ;
s0 : next_state = s1;
s1 : next_state = s2;
s2 : next_state = s3;
s3 : next_state = idle;
default : next_state = idle;
endcase
end
assign shift_ena = (state == s0) |(state == s1) |(state == s2) |(state == s3) ;
141、complete FSM
parameter S = 4'd0, S1 = 4'd1, S11 = 4'd2, S110 = 4'd3;
parameter B0 = 4'd4, B1 = 4'd5, B2 = 4'd6, B3 = 4'd7;
parameter Count = 4'd8, Wait = 4'd9;
reg [3:0] current_state, next_state;
always @(*) begin
case(current_state)
S: next_state = data ? S1 : S;
S1: next_state = data ? S11 : S;
S11: next_state = data ? S11 : S110;
S110: next_state = data ? B0 : S;
B0: next_state = B1;
B1: next_state = B2;
B2: next_state = B3;
B3: next_state = Count;
Count: next_state = done_counting ? Wait : Count;
Wait: next_state = ack ? S : Wait;
default: next_state = S;
endcase
end
always @(posedge clk) begin
if(reset) begin
current_state <= S;
end
else begin
current_state <= next_state;
end
end
assign shift_ena = current_state == B0 | current_state == B1 | current_state == B2 | current_state == B3;
assign counting = current_state == Count;
assign done = current_state == Wait;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】