Skip to content

Commit

Permalink
Implemented /WE (write_enable) to disable overwriting registers and t…
Browse files Browse the repository at this point in the history
…riggering noise restart, if last register is noise
  • Loading branch information
rejunity committed Oct 5, 2023
1 parent 1d43e30 commit a1f0df6
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 41 deletions.
12 changes: 10 additions & 2 deletions src/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ async def play_and_record_wav(dut):
# raw_sn76489_stream = "../music/DonkeyKongJunior-ingame.bbc50hz.bin"
# raw_sn76489_stream = "../music/1942.bbc50hz.sn76489.bin"
raw_sn76489_stream = "../music/CrazeeRider-title.bbc50hz.sn76489.bin"
# raw_sn76489_stream = "../music/MISSION76496.bbc50hz.sn76489.bin"
music, playback_rate = load_music(raw_sn76489_stream)
wave_filename = os.path.basename(raw_sn76489_stream).rstrip(".bin") + ".wav"
print(raw_sn76489_stream, "->", wave_filename)
Expand All @@ -97,18 +98,25 @@ async def play_and_record_wav(dut):
dut.rst_n.value = 1
print_chip_state(dut)

dut._log.info("record")
max_time = 125;
dut._log.info("record " + str(max_time) + " sec")

samples = []
n = 0
for frame in music:
cur_time = cocotb.utils.get_sim_time(units="ns")
if max_time > 0 and max_time * 1e9 <= cur_time:
write(wave_filename, sampling_rate, np.int16(samples))
break

print("---", n, len(samples), "---", [format(d, '08b') for d in frame], "---", "time in ms:", format(cur_time/1e6, "5.3f"),)
for val in frame:
dut.ui_in.value = val
dut.uio_in.value = 0 # /WE = 0, writes enabled
await ClockCycles(dut.clk, 1)
print_chip_state(dut)

dut.uio_in.value = 1 # # /WE = 1, writes disabled
#ns = cycles_per_frame * cycle_in_nanoseconds while ns > 0:

# i = cycles_per_frame - len(frame)
Expand All @@ -125,7 +133,7 @@ async def play_and_record_wav(dut):

while cocotb.utils.get_sim_time(units="ns") < cur_time + (1e9 / fps):
await Timer(nanoseconds_per_sample, units="ns", round_mode="round")
samples.append(int(dut.uo_out.value) * 64)
samples.append(int(dut.uo_out.value) * 128)
print_chip_state(dut)

# for i in range(int(cycles_per_frame / cycles_per_sample)):
Expand Down
87 changes: 48 additions & 39 deletions src/tt_um_rejunity_sn76489.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ module tt_um_rejunity_sn76489 #( parameter NUM_TONES = 3, parameter NUM_NOISES =
parameter ATTENUATION_CONTROL_BITS = 4,
parameter FREQUENCY_COUNTER_BITS = 10,
parameter NOISE_CONTROL_BITS = 3,
parameter CHANNEL_OUTPUT_BITS = 8,
parameter MASTER_OUTPUT_BITS = 7
// parameter CHANNEL_OUTPUT_BITS = 8,
// parameter MASTER_OUTPUT_BITS = 7
// parameter CHANNEL_OUTPUT_BITS = 6,
parameter CHANNEL_OUTPUT_BITS = 15,
parameter MASTER_OUTPUT_BITS = 8
) (
input wire [7:0] ui_in, // Dedicated inputs - connected to the input switches
output wire [7:0] uo_out, // Dedicated outputs - connected to the 7 segment display
Expand All @@ -17,10 +20,11 @@ module tt_um_rejunity_sn76489 #( parameter NUM_TONES = 3, parameter NUM_NOISES =
input wire clk, // clock
input wire rst_n // reset_n - low to reset
);
assign uio_oe[7:0] = {8{1'b1}}; // Bidirectional path set to output
assign uio_oe[7:0] = 8'b1111_1110; // Bidirectional path set to output, except the first /WE pin
assign uio_out[7:0] = {8{1'b0}};
wire reset = ! rst_n;

wire we = ! uio_in[0];
wire [7:0] data;
assign data = ui_in;

Expand Down Expand Up @@ -50,34 +54,36 @@ module tt_um_rejunity_sn76489 #( parameter NUM_TONES = 3, parameter NUM_NOISES =
restart_noise <= 0;
end else begin
restart_noise <= 0;
if (data[7] == 1'b1) begin
case(data[6:4])
3'b000 : control_tone_freq[0][3:0] <= data[3:0];
3'b010 : control_tone_freq[1][3:0] <= data[3:0];
3'b100 : control_tone_freq[2][3:0] <= data[3:0];
3'b110 :
begin
control_noise[0] <= data[2:0];
restart_noise <= 1;
end
3'b001 : control_attn[0] <= data[3:0];
3'b011 : control_attn[1] <= data[3:0];
3'b101 : control_attn[2] <= data[3:0];
3'b111 : control_attn[3] <= data[3:0];
default : begin end
endcase
latch_control_reg <= data[6:4];
end else begin
case(latch_control_reg)
3'b000 : control_tone_freq[0][9:4] <= data[5:0];
3'b010 : control_tone_freq[1][9:4] <= data[5:0];
3'b100 : control_tone_freq[2][9:4] <= data[5:0];
3'b001 : control_attn[0] <= data[3:0];
3'b011 : control_attn[1] <= data[3:0];
3'b101 : control_attn[2] <= data[3:0];
3'b111 : control_attn[3] <= data[3:0];
default : begin end
endcase
if (we) begin
if (data[7] == 1'b1) begin
case(data[6:4])
3'b000 : control_tone_freq[0][3:0] <= data[3:0];
3'b010 : control_tone_freq[1][3:0] <= data[3:0];
3'b100 : control_tone_freq[2][3:0] <= data[3:0];
3'b110 :
begin
control_noise[0] <= data[2:0];
restart_noise <= 1;
end
3'b001 : control_attn[0] <= data[3:0];
3'b011 : control_attn[1] <= data[3:0];
3'b101 : control_attn[2] <= data[3:0];
3'b111 : control_attn[3] <= data[3:0];
default : begin end
endcase
latch_control_reg <= data[6:4];
end else begin
case(latch_control_reg)
3'b000 : control_tone_freq[0][9:4] <= data[5:0];
3'b010 : control_tone_freq[1][9:4] <= data[5:0];
3'b100 : control_tone_freq[2][9:4] <= data[5:0];
3'b001 : control_attn[0] <= data[3:0];
3'b011 : control_attn[1] <= data[3:0];
3'b101 : control_attn[2] <= data[3:0];
3'b111 : control_attn[3] <= data[3:0];
default : begin end
endcase
end
end
end
end
Expand Down Expand Up @@ -152,19 +158,22 @@ module tt_um_rejunity_sn76489 #( parameter NUM_TONES = 3, parameter NUM_NOISES =
end
endgenerate

// assign uo_out[7:0] = (volumes[0] + volumes[1] + volumes[2] + volumes[3]);

// sum up all the channels, clamp to the highest value when overflown
localparam OVERFLOW_BITS = $clog2(NUM_CHANNELS);
localparam ACCUMULATOR_BITS = CHANNEL_OUTPUT_BITS + OVERFLOW_BITS;
wire [ACCUMULATOR_BITS-1:0] master;
assign master = (volumes[0] + volumes[1] + volumes[2] + volumes[3]);
assign uo_out[7:1] = (master[ACCUMULATOR_BITS-1 -: OVERFLOW_BITS] == 0) ? master[CHANNEL_OUTPUT_BITS-1 -: MASTER_OUTPUT_BITS] : {MASTER_OUTPUT_BITS{1'b1}};

pwm #(.VALUE_BITS(MASTER_OUTPUT_BITS)) pwm (
.clk(clk),
.reset(reset),
.value(uo_out[7:1]),
.out(uo_out[0])
);
// assign master = (volumes[0]);
// assign uo_out[7:1] = (master[ACCUMULATOR_BITS-1 -: OVERFLOW_BITS] == 0) ? master[CHANNEL_OUTPUT_BITS-1 -: MASTER_OUTPUT_BITS] : {MASTER_OUTPUT_BITS{1'b1}};
assign uo_out[7:0] = (master[ACCUMULATOR_BITS-1 -: OVERFLOW_BITS] == 0) ? master[CHANNEL_OUTPUT_BITS-1 -: MASTER_OUTPUT_BITS] : {MASTER_OUTPUT_BITS{1'b1}};

// pwm #(.VALUE_BITS(MASTER_OUTPUT_BITS)) pwm (
// .clk(clk),
// .reset(reset),
// .value(uo_out[7:1]),
// .out(uo_out[0])
// );

endmodule

0 comments on commit a1f0df6

Please sign in to comment.