012 HDLBits
Posted SilentLittleCat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了012 HDLBits相关的知识,希望对你有一定的参考价值。
大部分还是挺简单的哈,后面的一些题挺难的
256-to-1 4-bit multiplexer
https://hdlbits.01xz.net/wiki/Mux256to1v
256选1复用器
module top_module(
input [1023:0] in,
input [7:0] sel,
output [3:0] out );
错误答案
module top_module(
input [1023:0] in,
input [7:0] sel,
output [3:0] out );
// 最开始想这样写,报错,因为两个范围都是变量,解释器没有那么智能
assign out = in[sel * 4 + 3 : sel * 4];
endmodule
正确
module top_module (
input [1023:0] in,
input [7:0] sel,
output [3:0] out
);
// We can't part-select multiple bits without an error, but we can select one bit at a time,
// four times, then concatenate them together.
assign out = in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0];
// 也可用"indexed vector part select",后面那个数必须是常数
// assign out = in[sel*4 +: 4];
// assign out = in[sel*4+3 -: 4];
endmodule
Signed addition overflow
https://hdlbits.01xz.net/wiki/Exams/ece241_2014_q1c
a,b为补码表示,s为a+b的和,overflow表示符号位是否进位
module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
);
overflow发生在两个负数相加产生正数,或者两个正数相加产生负数的时候
module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
); //
assign s = a + b;
assign overflow = (s[7] && (~a[7]) && (~b[7])) || (~s[7] && (a[7] && b[7]));
endmodule
还有一种思路是捕获n-1到n的进位
Edge capture register
https://hdlbits.01xz.net/wiki/Edgecapture
这道题我觉得自己解的还可以哈,没有写子模块
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);
reg[31:0] d1, d2, out_tmp2;
assign out = out_tmp2;
always@(posedge clk) begin
d1 <= in;
end
wire[31:0] out_tmp;
assign out_tmp = d1 & (~in);
always@(posedge clk) begin
if(reset) out_tmp2 <= 32'd0;
else out_tmp2 <= out_tmp2 | out_tmp;
end
endmodule
Dual-edge triggered flip-flop
https://hdlbits.01xz.net/wiki/Dualedge
双边沿触发,感觉挺简单哈
module top_module (
input clk,
input d,
output q
);
always@(posedge clk or negedge clk) begin
q <= d;
end
endmodule
但是posedge clk or negedge clk
是不合法的敏感触发!!!
然后想捕获上边沿下边沿,搞了半天也没搞定
hint说这不是code问题,而是circuit问题,本想暴力搞定,然后看看答案,但搞了半天没搞定,去吃了个饭,双边沿触发就是每半个周期就把d传给q,所以这样解决
module top_module (
input clk,
input d,
output q
);
reg d1, d2;
always@(posedge clk) begin
d1 <= d; q <= d2;
end
always@(negedge clk) begin
d2 <= d; q <= d1;
end
endmodule
意料之中的multi driver,多驱动
简单改下
module top_module (
input clk,
input d,
output q
);
reg d1, d2;
always@(posedge clk) begin
d1 <= d;
end
always@(negedge clk) begin
d2 <= d;
end
assign q = clk ? d1 : d2;
endmodule
搞定,看下答案是这样写的,厉害了
module top_module(
input clk,
input d,
output q);
reg p, n;
// A positive-edge triggered flip-flop
always @(posedge clk)
p <= d ^ n;
// A negative-edge triggered flip-flop
always @(negedge clk)
n <= d ^ p;
// Why does this work?
// After posedge clk, p changes to d^n. Thus q = (p^n) = (d^n^n) = d.
// After negedge clk, n changes to p^n. Thus q = (p^n) = (p^p^n) = d.
// At each (positive or negative) clock edge, p and n FFs alternately
// load a value that will cancel out the other and cause the new value of d to remain.
assign q = p ^ n;
// Can't synthesize this.
/*always @(posedge clk, negedge clk) begin
q <= d;
end*/
endmodule
Conway’s Game of Life 16 * 16
https://hdlbits.01xz.net/wiki/Conwaylife
用c写其实很简单,但是翻译成Verilog稍微有点麻烦
module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q );
int tmp[255:0];
reg val;
always@(posedge clk) begin
if(load) q <= data;
else begin
for(int i = 0; i < 256; i = i + 1) begin
tmp[i] = 0;
for(int j = -1; j < 2; j = j + 1) begin
for(int k = -1; k < 2; k = k + 1) begin
if(!(j == 0 && k == 0)) begin
if(get_val(q, i, j, k))
tmp[i] = tmp[i] + 1;
end
end
end
case(tmp[i])
0, 1: q[i] <= 1'b0;
2: q[i] <= q[i];
3: q[i] <= 1'b1;
default: q[i] <= 1'b0;
endcase
end
end
end
function get_val(input[255:0] q, int i, int j, int k);
int row, col, nrow, ncol;
begin
row = i >> 4;
col = i % 16;
nrow = (row + j + 16) % 16;
ncol = (col + k + 16) % 16;
get_val = q[nrow * 16 + ncol];
end
endfunction
endmodule
Design a Moore FSM
https://hdlbits.01xz.net/wiki/Exams/ece241_2013_q4
上答案吧,我写的有点乱
module top_module (
input clk,
input reset,
input [3:1] s,
output reg fr3,
output reg fr2,
output reg fr1,
output reg dfr
);
// Give state names and assignments. I'm lazy, so I like to use decimal numbers.
// It doesn't really matter what assignment is used, as long as they're unique.
// We have 6 states here.
parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
reg [2:0] state, next; // Make sure these are big enough to hold the state encodings.
// Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.
always @(posedge clk) begin
if (reset) state <= A2;
else state <= next;
end
// Combinational always block for state transition logic. Given the current state and inputs,
// what should be next state be?
// Combinational always block: Use blocking assignments.
always@(*) begin
case (state)
A2: next = s[1] ? B1 : A2;
B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
D1: next = s[3] ? D1 : C2;
default: next = 'x;
endcase
end
// Combinational output logic. In this problem, a procedural block (combinational always block)
// is more convenient. Be careful not to create a latch.
always@(*) begin
case (state)
A2: fr3, fr2, fr1, dfr = 4'b1111;
B1: fr3, fr2, fr1, dfr = 4'b0110;
B2: fr3, fr2, fr1, dfr = 4'b0111;
C1: fr3, fr2, fr1, dfr = 4'b0010;
C2: fr3, fr2, fr1, dfr = 4'b0011;
D1: fr3, fr2, fr1, dfr = 4'b0000;
default: fr3, fr2, fr1, dfr = 'x;
endcase
end
endmodule
One-hot FSM
https://hdlbits.01xz.net/wiki/Fsm_onehot
使用one-hot编码实现下面的状态机
本来想的是
localparam S0 = 10'b00_0000_0001;
localparam S1 = 10'b00_0000_0010;
...
localparam S9 = 10'b10_0000_0000;
always@(*) begin
case(state)
S0: next_state = in ? S1 : state;
....
endcase
end
The testbench will test with non-one hot inputs to make sure you’re not trying to do something more complicated
但是测试数据里state可能不是one-hot,也就是说我们写复杂了
Suppose this state machine uses one-hot encoding, where state[0] through state[9] correspond to the states S0 though S9
也就说state[0] -> S0,state[9] -> S9,所以是每一位代表一个状态,而不是10位代表一个状态
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
assign next_state = in ? 2'b0, state[7] || state[6], state[5:1], state[9] || state[8] || state[0], 1'b0
: state[6], state[5], 1'b0, 6'd0, (|state[4:0]) || (|state[9:7]);
assign out1 = state[8] || state[9];
assign out2 = state[7] || state[9];
endmodule
Sequential circuit 10
https://hdlbits.01xz.net/wiki/Sim/circuit10
想了很久,暴力解决了
module top_module (
input clk,
input a,
input b,
output q,
output state );
reg a_last, b_last;
always@(posedge clk) begin
a_last <= a; b_last <= b;
end
always@(*) begin
case(a_last, b_last, a, b)
4'b0000, 4'b0011, 4'b1011, 4'b1000: begin
q = 1'b0; state = 1'b0;
end
4'b0001, 4'b0110, 4'b0010: begin
q = 1'b1; state = 1'b0;
end
4'b1100, 4'b1111, 4'b0100: begin
q = 1'b1; state = 1'b1;
end
4'b1110, 4'b1001: begin
q = 1'b0; state = 1'b1;
end
endcase
end
endmodule
178道题搞定
以上是关于012 HDLBits的主要内容,如果未能解决你的问题,请参考以下文章