📄 top_enc_rev4.v
字号:
`timescale 1ns / 10ps
// Rev 4: -Status/Control Registers Implemented
// -Controlability Fully Tested
// -Clock DLL implemente
`define BEHAVIOR = 1
module top_enc(clkin, rst, nce, awe, are, data, addr,clkout);
//
// Inputs & Outputs
//
input clkin; // 25MHz Clock
input rst; // Async Active-Low Reset
input nce; // Chip Enable (Ative-Low)
input awe; // Async Write Enable
input are; // Async Read Enable
input [5:0] addr; // Address Input
inout [24:0] data; // Data Output {toggle,doe[amp,huff],EOB,LC,DATA}
output clkout;
wire [12:0] din;
reg dstrb, rd_en;
reg [5:0] tempcontrol; // asynch updates
reg [5:0] control; // [CLKDIV,LC,ADDR3,ADDR2,ADDR1,ADDR0]
reg update; // Can only update control when set to 1
reg renew; // temp control reg updated
reg toggle; // Toggle bit to show valid data in fifo
reg bp; // block processing
//in_full, in_empty, out_full, out_empty, lc,
//dct_comp, qnr_comp, rle_comp, huff_comp,
//dctin,dctout,qnrin,qnrout,rlein,rleout,huffin,huffout]
reg [16:0] status;
wire eob;
assign rd_clk = ~are & ~nce;
BUFG wrclkg (.I(~awe & ~nce), .O(wr_clk));
//
// Clock DLL
//
CLKDLL dll (
.CLKIN(clkin),
.CLKFB(clk0b),
.RST(~rst),
.CLK0(clk0),
.CLK90(),
.CLK180(),
.CLK270(),
.CLK2X(),
.CLKDV(clk_dv),
.LOCKED()
);
BUFG clk0g (.I(clk0),.O(clk0b));
assign clk_mux = control[5] ? clk_dv : clk0;
BUFG clkg (.I(clk_mux), .O(clk));
assign clkout = clk;
//
// Control Register - Address 16
//
always @ (posedge wr_clk or negedge rst)
begin
if(~rst)
begin
renew <= 1'b0;
tempcontrol <= 6'h0;
end
else if(addr == 6'h10)
begin
renew <= 1'b1;
tempcontrol <= data[5:0]; //{clkdiv,LC,ADDR[3:0]}
end
else if(tempcontrol == control)
renew <= 1'b0;
end
always @ (posedge clk or negedge rst)
begin
if(~rst)
begin
control <= 6'h0;
update <= 1'b1;
end
else if(eob) update <= 1'b1;
else if(update && renew)
begin
update <= 1'b0;
control <= tempcontrol;
end
end
//
// Status Register - Address 32
//
wire in_full, in_empty, out_full, out_empty;
wire [11:0] encstat;
always @ (posedge clk or negedge rst)
begin
if(~rst)
status <= 13'h0;
else
status <= {control[4],in_full,in_empty,out_full,out_empty,encstat};
end
//
// Wires
//
wire [24:0] dout; // Output Data
assign data = (~are & ~nce & addr[5]) ? {8'h0,status} :
(~are & ~nce) ? dout : 25'bz;
//
// State Machine for Data Input to Encoder
// 7/21: only can input 1 block at a time with this
// configuration. should have capability to stream data
reg state;
reg [6:0] icnt;
reg [5:0] cnt;
reg up, up_icnt;
// How many items are in the input FIFO
always @ (posedge wr_clk or negedge rst)
begin
if(~rst)
begin
icnt <= 6'h0;
up_icnt <= 1'b0;
end
else if(up && !(&control[3:2]) && !(|addr[5:0])) //!(|addr[5:4]))
begin
icnt <= icnt - 7'h3f;
// To account for extra write to fifo in timing sims
//icnt <= icnt - 7'h40;
up_icnt <= 1'b1;
end
else if(!up && !(&control[3:2]) && !(|addr[5:4]))
begin
up_icnt <= 1'b0;
icnt <= icnt + 1;
end
end
always @ (posedge clk or negedge rst)
begin
if(~rst)
begin
dstrb <= 1'b0;
rd_en <= 1'b0;
state <= 1'b0;
cnt <= 6'h0;
bp <= 1'b0;
up <= 1'b0;
end
// Input to Huff Does not Require a block in the FIFO
else if(&control[3:2])
begin
case(state)
1'b0:
begin
rd_en <= ~in_empty ? 1'b1 : 1'b0;
dstrb <= 1'b0;
state <= ~in_empty ? 1'b1 : 1'b0;
end
1'b1:
begin
rd_en <= 1'b0;
dstrb <= 1'b1;
state <= 1'b0;
end
endcase
end
// FDCT,QNR,RLE all require full block in FIFO prior to dstrb
else if(up_icnt && up)
up <= 1'b0;
else if((icnt >= 7'h3f) && !bp && !up)
begin
bp <= 1'b1;
state <= 1'b0;
rd_en <= 1'b0;
up <= 1'b1;
end
else if(bp)
begin
bp <= &cnt ? 1'b0 : 1'b1;
//cnt <= rd_en ? cnt + 1 : cnt;
cnt <= cnt + 1;
if(!control[3]) //QNR & FDCT require dstrb 1 clk prior to data
begin
case(state)
1'b0:
begin
rd_en <= 1'b1;
dstrb <= 1'b1;
state <= 1'b1;
end
1'b1:
begin
rd_en <= 1'b1;
dstrb <= 1'b0;
state <= 1'b1;
end
endcase
end
else // RLE Requires dstrb at same time as data
begin
case(state)
1'b0:
begin
rd_en <= 1'b1;
dstrb <= 1'b0;
state <= !cnt ? 1'b1 : 1'b0;
end
1'b1:
begin
rd_en <= 1'b1;
dstrb <= 1'b1;
state <= 1'b0;
end
endcase
end
end
else
begin
rd_en <= 1'b0;
dstrb <= 1'b0;
state <= 1'b0;
end
end
//
// Instantiate Input FIFO
//
in_fifo in_fifo(
.din(data[12:0]), //{LC,DATA}
.wr_en(~nce),
.wr_clk(wr_clk && !(|addr[5:4])),
.rd_en(rd_en), // Read Enable from state machine
.rd_clk(clk),
.ainit(~rst), // FIFO reset active high
.dout(din),
.full(in_full),
.empty(in_empty)
);
//
// Instantiate JPEG Encoder
//
wire [19:0] do_enc; //Output of encoder
wire [1:0] doe;
jpeg_encoder enc(
.clk(clk),
.rst(rst),
.lc(control[4]),
.dstrb(dstrb),
.din(din[11:0]),
.addr(control[3:0]),
.eob(eob),
.doe(doe),
.dout(do_enc),
.encstat(encstat)
);
//
// toggle bit
//
assign d = |doe & ~clk;
always @ (posedge d or negedge rst)
begin
if(~rst)
toggle <= 1'b0;
else
toggle <= ~toggle;
end
//
// Instantiate Output FIFO
//
out_fifo out_fifo(
.din({toggle,eob,doe,control[4],do_enc}), //24-bit
.wr_en(|doe),
.wr_clk(~clk),
.rd_en(~nce),
.rd_clk(rd_clk && !(|addr[5:4])),
.ainit(~rst),
.dout(dout[24:0]), //24-bit
.full(out_full),
.empty(out_empty)
);
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -