always @(posedge clk) q <= reset ? 8'b0 : d;
always @(posedge clk or posedge areset) q <= areset ? 8'b0 : d;
module top_module (
input clk,
input x,
output z
);
wire q1, q2, q2b, q3, q3b;
mydff d1(clk, x^q1, q1);
mydff d2(clk, x&q2b, q2, q2b);
mydff d3(clk, x|q3b, q3, q3b);
nor (z, q1, q2, q3);
endmodule
// 통과한 모듈
module mydff(input clk, d, output q, qb);
assign qb = ~q;
always @(posedge clk) q<=d;
endmodule
// 실패한 모듈
module mydff(input clk, d, output reg q, output reg qb);
always @(posedge clk) begin q<=d; qb<=~d; end
endmodule
두 번째 구현의 경우 첫 클럭 이전 reset state에서 q와 qb가 complementary가 되지 않아서 오답이라고 한다...장난까나
module top_module (
input clk,
input [7:0] in,
output [7:0] pedge
);
reg [7:0] previn;
integer i;
always @(posedge clk) begin
for (i = 0; i < 8; i += 1) pedge[i] <= (previn[i] == 0 && in[i] == 1) ? 1 : 0;
previn <= in;
end
endmodule
뭔가 되게 고생했었는데 생각보다 간단한 문제였다
문제 조건에 '한 사이클에 0에서 1로 변하는' 이라는 조건이 있는데 사이클 안에서 올라왔다 내려오면 어쩌지??같은 고민을 했으니 어렵지
매 사이클마다 이전 상태를 기록해 두고, 이전 상태가 0이고 현재 상태가 1인 경우에만 pedge를 1로 출력하면 해결할 수 있다.
module top_module(
input clk,
input [7:0] in,
output reg [7:0] pedge);
reg [7:0] d_last;
always @(posedge clk) begin
d_last <= in; // Remember the state of the previous cycle
pedge <= in & ~d_last; // A positive edge occurred if input was 0 and is now 1.
end
endmodule
근데 솔루션은 더 간단하게 풀었다
논리식으로 하니까 for문이 필요가 없군
module top_module (
input clk,
input [7:0] in,
output [7:0] anyedge
);
reg [7:0] previn;
always @(posedge clk) begin
previn <= in;
anyedge <= previn ^ in;
end
endmodule
그래서 이번엔 나도 스마트하게 풀었다
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);
reg [31:0] previn;
always @(posedge clk) begin
previn <= in;
if (reset) out <= 32'b0;
else out <= out | (previn & ~in);
end
endmodule
앞의 문제들과 달리 리셋 이전까지 출력이 1에서 안 내려간다. 기존 out과의 or 연산으로 해결했다.
module top_module (
input clk,
input d,
output reg q
);
// why does not works with prevclk??
reg qp, qn;
always @(posedge clk) qp <= d;
always @(negedge clk) qn <= d;
always @(clk) q <= clk ? qp : qn;
endmodule
하나의 레지스터 q에 두 개의 always 구문에서 접근할 수 없고, 하나의 신호 clk를 두 엣지 모두 감지하는 것 또한 불가능하므로 이런 구조를 사용해야 한다.
솔루션의 경우 좀 다른 방식을 취했다.
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 d^p. Thus q = (p^n) = (p^d^p) = 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;
endmodule