Skip to content

Commit

Permalink
gateware/firmware: for now revert buf_fifo of jpeg encoder
Browse files Browse the repository at this point in the history
There is a bug somewhere (input of the encoder?) that need to be investigated (with simulations?)
Old buf_fifo seems to produce less artifacts (still some but not permanents) so we revert it for now until the issue is explained and fixed.
  • Loading branch information
enjoy-digital committed Nov 20, 2015
1 parent 1a34258 commit 74f5a8f
Show file tree
Hide file tree
Showing 12 changed files with 443 additions and 263 deletions.
5 changes: 2 additions & 3 deletions firmware/lm32/encoder.c
Expand Up @@ -171,9 +171,8 @@ void encoder_service(void) {
if (encoder_done() == 1) {
encoder_init(encoder_quality);
encoder_start(processor_h_active, processor_v_active);
encoder_reader_h_width_write(processor_h_active);
encoder_reader_v_width_write(processor_v_active);
encoder_reader_start_write(1);
encoder_reader_dma_length_write(processor_h_active*processor_v_active*2);
encoder_reader_dma_shoot_write(1);
frame_cnt++;
}
}
Expand Down
2 changes: 1 addition & 1 deletion firmware/lm32/hdmi_in0.c
Expand Up @@ -21,7 +21,7 @@ int hdmi_in0_fb_index;
#define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1)

#define HDMI_IN0_FRAMEBUFFERS_BASE 0x00000000
#define HDMI_IN0_FRAMEBUFFERS_SIZE 1920*1080*2
#define HDMI_IN0_FRAMEBUFFERS_SIZE 1280*720*2

unsigned int hdmi_in0_framebuffer_base(char n) {
return HDMI_IN0_FRAMEBUFFERS_BASE + n*HDMI_IN0_FRAMEBUFFERS_SIZE;
Expand Down
2 changes: 1 addition & 1 deletion firmware/lm32/hdmi_in1.c
Expand Up @@ -21,7 +21,7 @@ int hdmi_in1_fb_index;
#define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1)

#define HDMI_IN1_FRAMEBUFFERS_BASE 0x01000000
#define HDMI_IN1_FRAMEBUFFERS_SIZE 1920*1080*2
#define HDMI_IN1_FRAMEBUFFERS_SIZE 1280*720*2

unsigned int hdmi_in1_framebuffer_base(char n) {
return HDMI_IN1_FRAMEBUFFERS_BASE + n*HDMI_IN1_FRAMEBUFFERS_SIZE;
Expand Down
20 changes: 3 additions & 17 deletions firmware/lm32/processor.c
Expand Up @@ -252,20 +252,6 @@ static const struct video_timing video_modes[PROCESSOR_MODE_COUNT] = {
.v_blanking = 30,
.v_sync_offset = 5,
.v_sync_width = 5
},
// 1920x1080 @ 30.00 Hz ModeLine "1920x1080" 89.01 1920 2448 2492 2640 1080 1084 1089 1125 +HSync +VSync
{
.pixel_clock = 8901,

.h_active = 1920,
.h_blanking = 720,
.h_sync_offset = 528,
.h_sync_width = 44,

.v_active = 1080,
.v_blanking = 45,
.v_sync_offset = 4,
.v_sync_width = 5
}
};

Expand Down Expand Up @@ -499,16 +485,16 @@ void processor_update(void)
/* encoder */
#ifdef CSR_HDMI_IN0_BASE
if(processor_encoder_source == VIDEO_IN_HDMI_IN0) {
encoder_reader_base_write((hdmi_in0_framebuffer_base(hdmi_in0_fb_index)));
encoder_reader_dma_base_write((hdmi_in0_framebuffer_base(hdmi_in0_fb_index)));
}
#endif
#ifdef CSR_HDMI_IN1_BASE
if(processor_encoder_source == VIDEO_IN_HDMI_IN1) {
encoder_reader_base_write((hdmi_in1_framebuffer_base(hdmi_in1_fb_index)));
encoder_reader_dma_base_write((hdmi_in1_framebuffer_base(hdmi_in1_fb_index)));
}
#endif
if(processor_encoder_source == VIDEO_IN_PATTERN)
encoder_reader_base_write(pattern_framebuffer_base());
encoder_reader_dma_base_write(pattern_framebuffer_base());
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion firmware/lm32/processor.h
@@ -1,7 +1,7 @@
#ifndef __PROCESSOR_H
#define __PROCESSOR_H

#define PROCESSOR_MODE_COUNT 12
#define PROCESSOR_MODE_COUNT 11
#define PROCESSOR_MODE_DESCLEN 32

enum {
Expand Down
252 changes: 32 additions & 220 deletions gateware/encoder/__init__.py
Expand Up @@ -4,8 +4,6 @@
from migen.bus import wishbone
from migen.genlib.record import *
from migen.genlib.cdc import MultiReg
from migen.genlib.fsm import FSM, NextState
from migen.genlib.misc import chooser
from migen.bank.description import *
from migen.flow.actor import *
from migen.flow.network import *
Expand All @@ -16,230 +14,40 @@
from misoclib.mem.sdram.frontend import dma_lasmi

from gateware.csc.ycbcr422to444 import YCbCr422to444
from gateware.csc.ymodulator import YModulator


class EncoderReader(Module, AutoCSR):
def __init__(self, lasmim):
self.source = source = Source(EndpointDescription([("data", 128)]))
self.base = CSRStorage(32)
self.h_width = CSRStorage(16)
self.v_width = CSRStorage(16)
self.start = CSR()
self.done = CSRStatus()
self.source = source = Source(EndpointDescription([("data", 16)], packetized=True))

# # #

pixel_bits = 16 # ycbcr 4:2:2
burst_pixels = lasmim.dw//pixel_bits
alignment_bits = bits_for(lasmim.dw//8) - 1
reader = dma_lasmi.Reader(lasmim)
self.dma = spi.DMAReadController(reader, mode=spi.MODE_SINGLE_SHOT)

self.submodules.reader = reader = dma_lasmi.Reader(lasmim)
self.submodules.converter = structuring.Converter(EndpointDescription([("data", lasmim.dw)]),
EndpointDescription([("data", 128)]),
reverse=True)
self.comb += [
Record.connect(reader.data, self.converter.sink, leave_out=set(["d"])),
self.converter.sink.data.eq(reader.data.d),
Record.connect(self.converter.source, source)
]
pack_factor = lasmim.dw//16
packed_dat = structuring.pack_layout(16, pack_factor)
cast = structuring.Cast(lasmim.dw, packed_dat)
unpack = structuring.Unpack(pack_factor, [("data", 16)], reverse=True)

base = self.base.storage
h_width = self.h_width.storage
v_width = self.v_width.storage
start = self.start.r & self.start.re
done = self.done.status

h_clr = Signal()
h_clr_lsb = Signal()
h_inc = Signal()
h = Signal(16)
h_next = Signal(16)
self.comb += h_next.eq(h + burst_pixels)
self.sync += \
If(h_clr,
h.eq(0)
).Elif(h_clr_lsb,
h[:3].eq(0),
h[3:].eq(h[3:])
).Elif(h_inc,
h.eq(h_next)
)
# graph
g = DataFlowGraph()
g.add_pipeline(self.dma, cast, unpack)
self.submodules += CompositeActor(g)
self.comb += Record.connect(unpack.source, source)

v_clr = Signal()
v_inc = Signal()
v_dec7 = Signal()
v = Signal(16)
self.sync += \
If(v_clr,
v.eq(0)
).Elif(v_inc,
v.eq(v + 1)
).Elif(v_dec7,
v.eq(v - 7)
If(self.dma._busy.status == 0,
source.sop.eq(1),
).Elif(source.stb & source.ack,
source.sop.eq(0)
)

self.submodules.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
h_clr.eq(1),
v_clr.eq(1),
If(start,
NextState("READ")
).Else(
done.eq(1)
)
)
fsm.act("READ",
reader.address.stb.eq(1),
If(reader.address.ack,
# last burst of 8 pixels
If(h_next[:3] == 0,
# last line of a block of 8 pixels
If(v[:3] == 7,
# last block of a line
If(h >= h_width - burst_pixels,
h_clr.eq(1),
v_inc.eq(1),
# last line
If(v >= v_width - 1,
NextState("IDLE")
)
).Else(
h_inc.eq(1),
v_dec7.eq(1)
)
).Else(
h_clr_lsb.eq(1),
v_inc.eq(1)
)
).Else(
h_inc.eq(1)
)
)
)

read_address = Signal(lasmim.aw + alignment_bits)
self.comb += [
read_address.eq(v * h_width + h),
reader.address.a.eq(base[alignment_bits:] +
read_address[alignment_bits - log2_int(pixel_bits//8):])
]


class EncoderBuffer(Module):
def __init__(self, dw):
self.sink = sink = Sink(EndpointDescription([("data", 128)]))
self.source = source = Source(EndpointDescription([("data", 16)]))

# # #

# mem
mem = Memory(128, 16)
write_port = mem.get_port(write_capable=True)
read_port = mem.get_port(async_read=True)
self.specials += mem, write_port, read_port

write_sel = Signal()
write_swap = Signal()
read_sel = Signal(reset=1)
read_swap = Signal()
self.sync += [
If(write_swap,
write_sel.eq(~write_sel)
),
If(read_swap,
read_sel.eq(~read_sel)
)
]


# write path
v_write_clr = Signal()
v_write_inc = Signal()
v_write = Signal(3)
self.sync += \
If(v_write_clr,
v_write.eq(0)
).Elif(v_write_inc,
v_write.eq(v_write + 1)
)

self.comb += [
write_port.adr.eq(v_write),
write_port.adr[-1].eq(write_sel),
write_port.dat_w.eq(sink.data),
write_port.we.eq(sink.stb & sink.ack)
]

self.submodules.write_fsm = write_fsm = FSM(reset_state="IDLE")
write_fsm.act("IDLE",
v_write_clr.eq(1),
If(write_sel != read_sel,
NextState("WRITE")
)
)
write_fsm.act("WRITE",
sink.ack.eq(1),
If(sink.stb,
If(v_write == 7,
write_swap.eq(1),
NextState("IDLE")
).Else(
v_write_inc.eq(1)
)
)
)

# read path
h_read_clr = Signal()
h_read_inc = Signal()
h_read = Signal(3)
self.sync += \
If(h_read_clr,
h_read.eq(0)
).Elif(h_read_inc,
h_read.eq(h_read + 1)
)

v_read_clr = Signal()
v_read_inc = Signal()
v_read = Signal(3)
self.sync += \
If(v_read_clr,
v_read.eq(0)
).Elif(v_read_inc,
v_read.eq(v_read + 1)
)

self.comb += [
read_port.adr.eq(v_read),
read_port.adr[-1].eq(read_sel),
chooser(read_port.dat_r, h_read, source.data, reverse=True)
]

self.submodules.read_fsm = read_fsm = FSM(reset_state="IDLE")
read_fsm.act("IDLE",
h_read_clr.eq(1),
v_read_clr.eq(1),
If(read_sel == write_sel,
read_swap.eq(1),
NextState("READ")
)
)
read_fsm.act("READ",
source.stb.eq(1),
If(source.ack,
If(h_read == 7,
h_read_clr.eq(1),
If(v_read == 7,
NextState("IDLE")
).Else(
v_read_inc.eq(1)
)
).Else(
h_read_inc.eq(1)
)
)
)
# irq
self.submodules.ev = EventManager()
self.ev.done = EventSourceProcess()
self.ev.finalize()
self.comb += self.ev.done.trigger.eq(self.dma._busy.status)


class EncoderBandwidth(Module, AutoCSR):
Expand All @@ -263,7 +71,7 @@ def __init__(self):

class Encoder(Module, AutoCSR):
def __init__(self, platform):
self.sink = Sink(EndpointDescription([("data", 16)]))
self.sink = Sink(EndpointDescription([("data", 16)], packetized=True))
self.source = Source([("data", 8)])
self.bus = wishbone.Interface()

Expand All @@ -277,6 +85,10 @@ def __init__(self, platform):
chroma_upsampler.sink.cb_cr.eq(self.sink.data[8:])
]

# encoder fifo
encoder_fifo_full = Signal()
self.comb += chroma_upsampler.source.ack.eq(~encoder_fifo_full)

# output fifo
output_fifo_almost_full = Signal()
self.submodules.output_fifo = output_fifo = SyncFIFO([("data", 8)], 1024)
Expand All @@ -301,11 +113,11 @@ def __init__(self, platform):
#o_OPB_toutSup=,
o_OPB_errAck=self.bus.err,

i_fdct_ack=chroma_upsampler.source.ack,
i_fdct_stb=chroma_upsampler.source.stb,
i_fdct_data=Cat(chroma_upsampler.source.y,
chroma_upsampler.source.cb,
chroma_upsampler.source.cr),
i_iram_wdata=Cat(chroma_upsampler.source.y,
chroma_upsampler.source.cb,
chroma_upsampler.source.cr),
i_iram_wren=chroma_upsampler.source.stb & ~encoder_fifo_full,
o_iram_fifo_afull=encoder_fifo_full,

o_ram_byte=output_fifo.sink.data,
o_ram_wren=output_fifo.sink.stb,
Expand Down

0 comments on commit 74f5a8f

Please sign in to comment.